Merge "qseecom: Change the library name."
diff --git a/Documentation/devicetree/bindings/arm/msm/msm_bus.txt b/Documentation/devicetree/bindings/arm/msm/msm_bus.txt
index fb72525..5f534a2 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm_bus.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm_bus.txt
@@ -1,6 +1,11 @@
 MSM Bus Scaling Driver
 
-The msm bus scaling driver provides the ability to configure
+The bus scaling driver builds the topology of chipsets by adding
+bus devices (fabrics/NoCs) to the kernel tree. The device-tree
+data for bus devices contains the register addresses for QoS
+related registers on each NoC/Fabric.
+
+The bus scaling driver also provides the ability to configure
 bus performance parameters across the entire chip-set.
 Various clients use MSM scaling APIs to request bandwidth
 between multiple master-slave pairs. The bus driver then finds
diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
index 104d6a2..032c814 100644
--- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
+++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
@@ -459,6 +459,11 @@
 - qcom,taiko-mclk-clk-freq : Master clock value given to codec. Some WCD9XXX
   codec can run at different mclk values. Mclk value can be 9.6MHz or 12.288MHz.
   This element represents the value for MCLK provided to codec.
+- prim-i2s-gpio-ws : Specifies gpio assigned for primary WS I2S pin.
+- prim-i2s-gpio-din : Specifies gpio assigned for primary DIN I2S pin.
+- prim-i2s-gpio-dout : Specifies gpio assigned for primary DOUT I2S pin.
+- prim-i2s-gpio-sclk : Specifies gpio assigned for primary SCLK I2S pin.
+- prim-i2s-gpio-mclk : Specifies gpio assigned for MCLK I2S pin.
 
 Example:
 
@@ -494,6 +499,11 @@
 			"DMIC6", "MIC BIAS4 External",
 			"MIC BIAS4 External", "Digital Mic6";
 			qcom,taiko-mclk-clk-freq = <12288000>;
+			prim-i2s-gpio-ws   =  <&msmgpio 12 0>;
+			prim-i2s-gpio-din  =  <&msmgpio 13 0>;
+			prim-i2s-gpio-dout =  <&msmgpio 14 0>;
+			prim-i2s-gpio-sclk =  <&msmgpio 15 0>;
+			prim-i2s-gpio-mclk =  <&msmgpio 71 0>;
 };
 
 * msm-adsp-loader
diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
index 015822f..8b7b31b 100644
--- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
@@ -147,6 +147,10 @@
 - qcom,descriptor-fifo-offset: descriptor fifo offset address
 - qcom,descriptor-fifo-size: descriptor fifo size
 
+Optional Properties for Subnode:
+- qcom,reset-bam-on-connect: If present then BAM is RESET before connecting
+  pipe. This may be required if BAM peripheral is also reset before connect.
+
 Optional properties :
 - qcom,ignore-core-reset-ack: If present then BAM ignores ACK from USB core
 	    while performing PIPE RESET
@@ -193,6 +197,7 @@
 			qcom,data-fifo-size = <0x4000>;
 			qcom,descriptor-fifo-offset = <0xf4000>;
 			qcom,descriptor-fifo-size = <0x1400>;
+			qcom,reset-bam-on-connect;
 		};
 
 		qcom,pipe3 {
diff --git a/Documentation/mmc/mmc-dev-attrs.txt b/Documentation/mmc/mmc-dev-attrs.txt
index 43453d0..d96b431 100644
--- a/Documentation/mmc/mmc-dev-attrs.txt
+++ b/Documentation/mmc/mmc-dev-attrs.txt
@@ -25,14 +25,14 @@
 	running parallel lmdd write and lmdd read operations and calculating
 	the max number of packed writes requests.
 
-	min_sectors_to_check_bkops_status	This attribute is used to
-	determine whether the status bit that indicates the need for BKOPS
-	should be checked. The value is stored in this attribute represents
-	the minimum number of sectors that needs to be changed in the device
-	(written or discarded) in order to require the status-bit of BKOPS
-	to be checked. The value can modified via sysfs by writing the
-	required value to:
-	/sys/block/<block_dev_name>/min_sectors_to_check_bkops_status
+	bkops_check_threshold	This attribute is used to determine whether
+	the status bit that indicates the need for BKOPS should be checked.
+	The value should be given in percentages of the card size.
+	This value is used to calculate the minimum number of sectors that
+	needs to be changed in the device (written or discarded) in order to
+	require the status-bit of BKOPS to be checked.
+	The value can modified via sysfs by writing the required value to:
+	/sys/block/<block_dev_name>/bkops_check_threshold
 
 SD and MMC Device Attributes
 ============================
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 23181d9..5a9cecf 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -782,6 +782,7 @@
 	select HAVE_CLK_PREPARE
 	select NEED_MACH_MEMORY_H
 	select NEED_MACH_IO_H
+	select SOC_BUS
 	help
 	  Support for Qualcomm MSM/QSD based systems.  This runs on the
 	  apps processor of the MSM/QSD and depends on a shared memory
diff --git a/arch/arm/boot/dts/msm8226-iommu.dtsi b/arch/arm/boot/dts/msm8226-iommu.dtsi
new file mode 100644
index 0000000..66a7848
--- /dev/null
+++ b/arch/arm/boot/dts/msm8226-iommu.dtsi
@@ -0,0 +1,37 @@
+/* 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/ "msm-iommu.dtsi"
+
+&jpeg_iommu {
+	status = "ok";
+};
+
+&mdp_iommu {
+	status = "ok";
+	/* HACK: set to -1 during pre-si due to lack of TZ */
+	qcom,iommu-secure-id = <0xFFFFFFFF>;
+};
+
+&venus_iommu {
+	status = "ok";
+	/* HACK: set to -1 during pre-si due to lack of TZ */
+	qcom,iommu-secure-id = <0xFFFFFFFF>;
+};
+
+&kgsl_iommu {
+	status = "ok";
+};
+
+&vfe_iommu {
+	status = "ok";
+};
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index 36bcdd7..bc07d84 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.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
@@ -13,6 +13,7 @@
 /include/ "skeleton.dtsi"
 /include/ "msm8226-ion.dtsi"
 /include/ "msm-gdsc.dtsi"
+/include/ "msm8226-iommu.dtsi"
 
 / {
 	model = "Qualcomm MSM 8226";
diff --git a/arch/arm/boot/dts/msm8974-liquid.dtsi b/arch/arm/boot/dts/msm8974-liquid.dtsi
index 81f8c09..7368788 100644
--- a/arch/arm/boot/dts/msm8974-liquid.dtsi
+++ b/arch/arm/boot/dts/msm8974-liquid.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
@@ -121,6 +121,7 @@
 			atmel,panel-coords = <0 0 1080 1920>;
 			atmel,display-coords = <0 0 1080 1920>;
 			atmel,i2c-pull-up;
+			atmel,no-force-update;
 			atmel,cfg_1 {
 				atmel,family-id = <0xa2>;
 				atmel,variant-id = <0x00>;
@@ -562,6 +563,12 @@
 	};
 };
 
+&slim_msm {
+	taiko_codec {
+		qcom,cdc-micbias2-ext-cap;
+	};
+};
+
 &spi_epm {
 	epm-adc@0 {
 		compatible = "cy,epm-adc-cy8c5568lti-114";
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 6a9a071..9be99af 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -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
@@ -99,6 +99,8 @@
 
 	usb_otg: usb@f9a55000 {
 		compatible = "qcom,hsusb-otg";
+		status = "disabled";
+
 		reg = <0xf9a55000 0x400>;
 		interrupts = <0 134 0 0 140 0>;
 		interrupt-names = "core_irq", "async_irq";
@@ -1114,6 +1116,7 @@
 			qcom,data-fifo-size = <0x1800>;
 			qcom,descriptor-fifo-offset = <0xf4000>;
 			qcom,descriptor-fifo-size = <0x1400>;
+			qcom,reset-bam-on-connect;
 		};
 
 		qcom,pipe3 {
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 75a0ae5..2fbff6d 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -81,7 +81,7 @@
 		vbus_otg-supply = <&usb_vbus>;
 
 		qcom,hsusb-otg-phy-type = <2>;
-		qcom,hsusb-otg-mode = <1>;
+		qcom,hsusb-otg-mode = <3>;
 		qcom,hsusb-otg-otg-control = <1>;
 		qcom,hsusb-otg-disable-reset;
 	};
@@ -470,6 +470,11 @@
 			"DMIC6", "MIC BIAS4 External",
 			"MIC BIAS4 External", "Digital Mic6";
 			qcom,taiko-mclk-clk-freq = <12288000>;
+			prim-i2s-gpio-ws   = <&msmgpio 12 0>;
+			prim-i2s-gpio-din  = <&msmgpio 13 0>;
+			prim-i2s-gpio-dout = <&msmgpio 14 0>;
+			prim-i2s-gpio-sclk = <&msmgpio 15 0>;
+			prim-i2s-gpio-mclk = <&msmgpio 71 0>;
 	};
 
 	qcom,msm-adsp-loader {
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index 1fadd28..136cb5a 100644
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -1,7 +1,6 @@
 # CONFIG_ARM_PATCH_PHYS_VIRT is not set
 CONFIG_EXPERIMENTAL=y
 CONFIG_LOCALVERSION="-perf"
-# CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SYSVIPC=y
 CONFIG_RCU_FAST_NO_HZ=y
 CONFIG_IKCONFIG=y
@@ -217,7 +216,7 @@
 CONFIG_BT_HIDP=y
 CONFIG_BT_HCISMD=y
 CONFIG_MSM_BT_POWER=y
-CONFIG_CFG80211=m
+CONFIG_CFG80211=y
 CONFIG_RFKILL=y
 CONFIG_GENLOCK=y
 CONFIG_GENLOCK_MISCDEVICE=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index 87f72f6..eb3c315 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -1,6 +1,5 @@
 # CONFIG_ARM_PATCH_PHYS_VIRT is not set
 CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SYSVIPC=y
 CONFIG_RCU_FAST_NO_HZ=y
 CONFIG_IKCONFIG=y
@@ -219,7 +218,7 @@
 CONFIG_BT_HIDP=y
 CONFIG_BT_HCISMD=y
 CONFIG_MSM_BT_POWER=y
-CONFIG_CFG80211=m
+CONFIG_CFG80211=y
 CONFIG_RFKILL=y
 CONFIG_GENLOCK=y
 CONFIG_GENLOCK_MISCDEVICE=y
diff --git a/arch/arm/configs/msm9625_defconfig b/arch/arm/configs/msm9625_defconfig
index 0b003fd..decd8f2 100644
--- a/arch/arm/configs/msm9625_defconfig
+++ b/arch/arm/configs/msm9625_defconfig
@@ -238,6 +238,7 @@
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
 CONFIG_YAFFS_FS=y
+CONFIG_EXT3_FS=y
 CONFIG_YAFFS_DISABLE_TAGS_ECC=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ASCII=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 5b0ac52..afb9ab6 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -1568,6 +1568,16 @@
 	  to perform QMI message marshaling and transport them over IPC
 	  Router.
 
+config MSM_TEST_QMI_CLIENT
+	depends on MSM_QMI_INTERFACE
+	bool "MSM TEST QMI CLIENT"
+	help
+	  The sample QMI client provides a test code for QMI usage. The
+	  test_service client driver uses QMI interface library to send
+	  and receive QMI messages over IPC Router. The test code sends
+	  a synchronous QMI request to the test_service and handles the
+	  QMI responses.
+
 config MSM_ONCRPCROUTER_DEBUG
 	depends on MSM_ONCRPCROUTER
 	default y
@@ -2742,4 +2752,9 @@
 	  stand alone power collapse operation. Selecting this option
 	  ensures that they are always off.
 
+config MSM_UARTDM_Core_v14
+	bool "Use MSM BLSP based HSUART Core v1.4"
+	depends on SERIAL_MSM_HS
+	help
+		Select if BLSP based UART Core v.14 or higher is present.
 endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 594bb5f..2d617a9 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -138,6 +138,7 @@
 obj-$(CONFIG_MSM_IPC_ROUTER)+= ipc_socket.o
 obj-$(CONFIG_MSM_IPC_ROUTER_SECURITY)+= msm_ipc_router_security.o
 obj-$(CONFIG_MSM_QMI_INTERFACE) += msm_qmi_interface.o
+obj-$(CONFIG_MSM_TEST_QMI_CLIENT) += kernel_test_service_v01.o test_qmi_client.o
 obj-$(CONFIG_DEBUG_FS) += smd_rpc_sym.o
 obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter_servers.o
 obj-$(CONFIG_MSM_ONCRPCROUTER) += smd_rpcrouter_clients.o
diff --git a/arch/arm/mach-msm/acpuclock-8064.c b/arch/arm/mach-msm/acpuclock-8064.c
index db77a34..e8c7680 100644
--- a/arch/arm/mach-msm/acpuclock-8064.c
+++ b/arch/arm/mach-msm/acpuclock-8064.c
@@ -122,7 +122,7 @@
 	[3]  = { {  540000, HFPLL, 2, 0x28 }, 1050000, 1050000, 2 },
 	[4]  = { {  594000, HFPLL, 1, 0x16 }, 1050000, 1050000, 2 },
 	[5]  = { {  648000, HFPLL, 1, 0x18 }, 1050000, 1050000, 4 },
-	[6]  = { {  702000, HFPLL, 1, 0x1A }, 1050000, 1050000, 4 },
+	[6]  = { {  702000, HFPLL, 1, 0x1A }, 1150000, 1150000, 4 },
 	[7]  = { {  756000, HFPLL, 1, 0x1C }, 1150000, 1150000, 4 },
 	[8]  = { {  810000, HFPLL, 1, 0x1E }, 1150000, 1150000, 4 },
 	[9]  = { {  864000, HFPLL, 1, 0x20 }, 1150000, 1150000, 4 },
@@ -137,18 +137,18 @@
 
 static struct acpu_level tbl_slow[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000 },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(6),   975000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   975000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(6),  1000000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),  1000000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(6),  1025000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),  1025000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(6),  1075000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),  1075000 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(6),  1100000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),  1100000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(6),  1125000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),  1125000 },
+	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(5),   975000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   975000 },
+	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(5),  1000000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),  1000000 },
+	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(5),  1025000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),  1025000 },
+	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(5),  1075000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),  1075000 },
+	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(5),  1100000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1100000 },
+	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(5),  1125000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1125000 },
 	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(15), 1175000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1175000 },
 	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(15), 1200000 },
@@ -163,18 +163,18 @@
 
 static struct acpu_level tbl_nom[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   900000 },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(6),   925000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   925000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(6),   950000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   950000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(6),   975000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   975000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(6),  1025000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),  1025000 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(6),  1050000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),  1050000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(6),  1075000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),  1075000 },
+	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(5),   925000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   925000 },
+	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(5),   950000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   950000 },
+	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(5),   975000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   975000 },
+	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(5),  1025000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),  1025000 },
+	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(5),  1050000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1050000 },
+	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(5),  1075000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1075000 },
 	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(15), 1125000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1125000 },
 	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(15), 1150000 },
@@ -189,18 +189,18 @@
 
 static struct acpu_level tbl_fast[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   850000 },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(6),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   875000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(6),   900000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   900000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(6),   925000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   925000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(6),   975000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   975000 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(6),  1000000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),  1000000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(6),  1025000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),  1025000 },
+	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(5),   875000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
+	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(5),   900000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   900000 },
+	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(5),   925000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   925000 },
+	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(5),   975000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   975000 },
+	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(5),  1000000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1000000 },
+	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(5),  1025000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1025000 },
 	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(15), 1075000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1075000 },
 	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(15), 1100000 },
@@ -215,18 +215,18 @@
 
 static struct acpu_level tbl_faster[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   850000 },
-	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(6),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   875000 },
-	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(6),   900000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   900000 },
-	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(6),   925000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   925000 },
-	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(6),   962500 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   962500 },
-	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(6),   975000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   975000 },
-	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(6),  1000000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),  1000000 },
+	{ 0, {   432000, HFPLL, 2, 0x20 }, L2(5),   875000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
+	{ 0, {   540000, HFPLL, 2, 0x28 }, L2(5),   900000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   900000 },
+	{ 0, {   648000, HFPLL, 1, 0x18 }, L2(5),   925000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   925000 },
+	{ 0, {   756000, HFPLL, 1, 0x1C }, L2(5),   962500 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   962500 },
+	{ 0, {   864000, HFPLL, 1, 0x20 }, L2(5),   975000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   975000 },
+	{ 0, {   972000, HFPLL, 1, 0x24 }, L2(5),  1000000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1000000 },
 	{ 0, {  1080000, HFPLL, 1, 0x28 }, L2(15), 1050000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1050000 },
 	{ 0, {  1188000, HFPLL, 1, 0x2C }, L2(15), 1075000 },
@@ -241,12 +241,12 @@
 
 static struct acpu_level tbl_PVS0_1700MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   950000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   950000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   962500 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),  1000000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),  1025000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),  1037500 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   950000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   950000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   962500 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),  1000000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1025000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1037500 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1075000 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1087500 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1125000 },
@@ -259,12 +259,12 @@
 
 static struct acpu_level tbl_PVS1_1700MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   950000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   950000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   962500 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   975000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),  1000000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),  1012500 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   950000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   950000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   962500 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   975000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),  1000000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1012500 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1037500 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1050000 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1087500 },
@@ -277,12 +277,12 @@
 
 static struct acpu_level tbl_PVS2_1700MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   925000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   925000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   925000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   925000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   937500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   950000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),   975000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   925000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   925000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   925000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   937500 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   950000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   975000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1000000 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1012500 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1037500 },
@@ -295,12 +295,12 @@
 
 static struct acpu_level tbl_PVS3_1700MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   900000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   900000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   900000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   900000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   900000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   925000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),   950000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   900000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   900000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   900000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   900000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   925000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   950000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  975000 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  987500 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1000000 },
@@ -313,12 +313,12 @@
 
 static struct acpu_level tbl_PVS4_1700MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   875000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   875000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   875000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   887500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   900000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),   925000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  950000 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  962500 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15),  975000 },
@@ -331,12 +331,12 @@
 
 static struct acpu_level tbl_PVS5_1700MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   875000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   875000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   875000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   887500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   900000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),   925000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  937500 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  950000 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15),  962500 },
@@ -349,12 +349,12 @@
 
 static struct acpu_level tbl_PVS6_1700MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   875000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   875000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   875000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   887500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   900000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),   925000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  937500 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  950000 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15),  962500 },
@@ -367,12 +367,12 @@
 
 static struct acpu_level tbl_PVS0_2000MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   950000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   950000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   950000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   950000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   962500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   975000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),  1000000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   950000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   950000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   950000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   962500 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   975000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),  1000000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1025000 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1037500 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1062500 },
@@ -386,12 +386,12 @@
 
 static struct acpu_level tbl_PVS1_2000MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   925000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   925000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   925000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   925000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   937500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   950000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),   975000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   925000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   925000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   925000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   937500 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   950000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   975000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15), 1000000 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15), 1012500 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1037500 },
@@ -405,12 +405,12 @@
 
 static struct acpu_level tbl_PVS2_2000MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   900000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   900000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   900000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   900000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   912500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   925000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),   950000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   900000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   900000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   900000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   912500 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   925000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   950000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  975000 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  987500 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1012500 },
@@ -424,12 +424,12 @@
 
 static struct acpu_level tbl_PVS3_2000MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   900000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   900000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   900000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   900000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   900000 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   912500 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),   937500 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   900000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   900000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   900000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   900000 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   912500 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   937500 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  962500 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  975000 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15), 1000000 },
@@ -443,12 +443,12 @@
 
 static struct acpu_level tbl_PVS4_2000MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   875000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   875000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   875000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   887500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   900000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),   925000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  950000 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  962500 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15),  975000 },
@@ -462,12 +462,12 @@
 
 static struct acpu_level tbl_PVS5_2000MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   875000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   875000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   875000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   887500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   900000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),   925000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  937500 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  950000 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15),  962500 },
@@ -481,12 +481,12 @@
 
 static struct acpu_level tbl_PVS6_2000MHz[] __initdata = {
 	{ 1, {   384000, PLL_8, 0, 0x00 }, L2(0),   875000 },
-	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(6),   875000 },
-	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(6),   875000 },
-	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(6),   875000 },
-	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(6),   887500 },
-	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(6),   900000 },
-	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(6),   925000 },
+	{ 1, {   486000, HFPLL, 2, 0x24 }, L2(5),   875000 },
+	{ 1, {   594000, HFPLL, 1, 0x16 }, L2(5),   875000 },
+	{ 1, {   702000, HFPLL, 1, 0x1A }, L2(5),   875000 },
+	{ 1, {   810000, HFPLL, 1, 0x1E }, L2(5),   887500 },
+	{ 1, {   918000, HFPLL, 1, 0x22 }, L2(5),   900000 },
+	{ 1, {  1026000, HFPLL, 1, 0x26 }, L2(5),   925000 },
 	{ 1, {  1134000, HFPLL, 1, 0x2A }, L2(15),  937500 },
 	{ 1, {  1242000, HFPLL, 1, 0x2E }, L2(15),  950000 },
 	{ 1, {  1350000, HFPLL, 1, 0x32 }, L2(15),  962500 },
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
index f6dd2ea..aef937a 100644
--- a/arch/arm/mach-msm/board-8064-pmic.c
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -183,6 +183,8 @@
 /* Initial PM8XXX MPP configurations */
 static struct pm8xxx_mpp_init pm8xxx_mpps[] __initdata = {
 	PM8921_MPP_INIT(3, D_OUTPUT, PM8921_MPP_DIG_LEVEL_VPH, DOUT_CTRL_LOW),
+	/* External 5V regulator enable; shared by HDMI and USB_OTG switches. */
+	PM8921_MPP_INIT(7, D_OUTPUT, PM8921_MPP_DIG_LEVEL_VPH, DOUT_CTRL_LOW),
 	PM8921_MPP_INIT(8, D_OUTPUT, PM8921_MPP_DIG_LEVEL_S4, DOUT_CTRL_LOW),
 	/*MPP9 is used to detect docking station connection/removal on Liquid*/
 	PM8921_MPP_INIT(9, D_INPUT, PM8921_MPP_DIG_LEVEL_S4, DIN_TO_INT),
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index 1a8e7e4..a6f0e32 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -299,7 +299,6 @@
 };
 VREG_CONSUMERS(EXT_5V) = {
 	REGULATOR_SUPPLY("ext_5v",		NULL),
-	REGULATOR_SUPPLY("ext_ddr3",		NULL),
 	REGULATOR_SUPPLY("vbus",		"msm_ehci_host.0"),
 };
 
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index f782dfe..4ebe5dc 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -10,6 +10,7 @@
  * GNU General Public License for more details.
  *
  */
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/bitops.h>
 #include <linux/platform_device.h>
@@ -2072,7 +2073,8 @@
 {
 	msm_shared_ram_phys = MSM_SHARED_RAM_PHYS;
 	msm_map_apq8064_io();
-	if (socinfo_init() < 0)
+
+	if (IS_ERR_OR_NULL(socinfo_init()))
 		pr_err("socinfo_init() failed!\n");
 }
 
@@ -3538,20 +3540,6 @@
 
 }
 
-static void enable_ddr3_regulator(void)
-{
-	static struct regulator *ext_ddr3;
-
-	/* Use MPP7 output state as a flag for PCDDR3 presence. */
-	if (gpio_get_value_cansleep(PM8921_MPP_PM_TO_SYS(7)) > 0) {
-		ext_ddr3 = regulator_get(NULL, "ext_ddr3");
-		if (IS_ERR(ext_ddr3) || ext_ddr3 == NULL)
-			pr_err("Could not get MPP7 regulator\n");
-		else
-			regulator_enable(ext_ddr3);
-	}
-}
-
 static void enable_avc_i2c_bus(void)
 {
 	int avc_i2c_en_mpp = PM8921_MPP_PM_TO_SYS(8);
@@ -3582,7 +3570,7 @@
 	platform_device_register(&msm_gpio_device);
 	msm_tsens_early_init(&apq_tsens_pdata);
 	msm_thermal_init(&msm_thermal_pdata);
-	if (socinfo_init() < 0)
+	if (IS_ERR_OR_NULL(socinfo_init()))
 		pr_err("socinfo_init() failed!\n");
 	BUG_ON(msm_rpm_init(&apq8064_rpm_data));
 	BUG_ON(msm_rpmrs_levels_init(&msm_rpmrs_data));
@@ -3656,7 +3644,6 @@
 			ARRAY_SIZE(common_i2s_devices));
 	}
 
-	enable_ddr3_regulator();
 	rpmrs_level =
 		msm_rpmrs_levels[MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT];
 	msm_hsic_pdata.swfi_latency = rpmrs_level.latency_us;
diff --git a/arch/arm/mach-msm/board-8092.c b/arch/arm/mach-msm/board-8092.c
index cbd257f..c7d01bf 100644
--- a/arch/arm/mach-msm/board-8092.c
+++ b/arch/arm/mach-msm/board-8092.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
@@ -10,6 +10,7 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/of.h>
@@ -78,9 +79,6 @@
 static void __init mpq8092_map_io(void)
 {
 	msm_map_mpq8092_io();
-	if (socinfo_init() < 0)
-		pr_err("%s: socinfo_init() failed\n", __func__);
-
 }
 
 static struct of_dev_auxdata mpq8092_auxdata_lookup[] __initdata = {
@@ -98,6 +96,11 @@
 static void __init mpq8092_init(void)
 {
 	struct of_dev_auxdata *adata = mpq8092_auxdata_lookup;
+	struct device *parent;
+
+	parent = socinfo_init();
+	if (IS_ERR_OR_NULL(parent))
+		pr_err("%s: socinfo_init() failed\n", __func__);
 
 	mpq8092_init_gpiomux();
 	msm_clock_init(&mpq8092_clock_init_data);
diff --git a/arch/arm/mach-msm/board-8226.c b/arch/arm/mach-msm/board-8226.c
index 2f2eb2c..54531a6 100644
--- a/arch/arm/mach-msm/board-8226.c
+++ b/arch/arm/mach-msm/board-8226.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
@@ -10,6 +10,7 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/platform_device.h>
@@ -75,6 +76,18 @@
 	CLK_DUMMY("bus_clk",	NULL,		"msm_sdcc.2", OFF),
 	CLK_DUMMY("core_clk",	NULL,		"f9928000.spi", OFF),
 	CLK_DUMMY("iface_clk",	NULL,		"f9928000.spi", OFF),
+	CLK_DUMMY("iface_clk",		NULL, "fda64000.qcom,iommu", OFF),
+	CLK_DUMMY("core_clk",		NULL, "fda64000.qcom,iommu", OFF),
+	CLK_DUMMY("iface_clk",		NULL, "fda44000.qcom,iommu", OFF),
+	CLK_DUMMY("core_clk",		NULL, "fda44000.qcom,iommu", OFF),
+	CLK_DUMMY("iface_clk",		NULL, "fd928000.qcom,iommu", OFF),
+	CLK_DUMMY("core_clk",		NULL, "fd928000.qcom,iommu", OFF),
+	CLK_DUMMY("core_clk",		NULL, "fdb10000.qcom,iommu", OFF),
+	CLK_DUMMY("iface_clk",		NULL, "fdb10000.qcom,iommu", OFF),
+	CLK_DUMMY("alt_core_clk",	NULL, "fdb10000.qcom,iommu", OFF),
+	CLK_DUMMY("iface_clk",		NULL, "fdc84000.qcom,iommu", OFF),
+	CLK_DUMMY("alt_core_clk",	NULL, "fdc84000.qcom,iommu", OFF),
+	CLK_DUMMY("core_clk",		NULL, "fdc84000.qcom,iommu", OFF),
 };
 
 static struct clock_init_data msm_dummy_clock_init_data __initdata = {
@@ -109,14 +122,15 @@
 void __init msm8226_init(void)
 {
 	struct of_dev_auxdata *adata = msm8226_auxdata_lookup;
+	struct device *parent;
+
+	parent = socinfo_init();
+	if (IS_ERR_OR_NULL(parent))
+		pr_err("%s: socinfo_init() failed\n", __func__);
 
 	msm8226_init_gpiomux();
 
 	msm_clock_init(&msm_dummy_clock_init_data);
-
-	if (socinfo_init() < 0)
-		pr_err("%s: socinfo_init() failed\n", __func__);
-
 	of_platform_populate(NULL, of_default_bus_match_table, adata, NULL);
 }
 
diff --git a/arch/arm/mach-msm/board-8910.c b/arch/arm/mach-msm/board-8910.c
index 2ff4567..f779c1f 100644
--- a/arch/arm/mach-msm/board-8910.c
+++ b/arch/arm/mach-msm/board-8910.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
@@ -10,6 +10,7 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/platform_device.h>
@@ -86,6 +87,11 @@
 void __init msm8910_init(void)
 {
 	struct of_dev_auxdata *adata = msm8910_auxdata_lookup;
+	struct device *parent;
+
+	parent = socinfo_init();
+	if (IS_ERR_OR_NULL(parent))
+		pr_err("%s: socinfo_init() failed\n", __func__);
 
 	msm8910_init_gpiomux();
 
@@ -93,10 +99,6 @@
 		msm_clock_init(&msm8910_rumi_clock_init_data);
 	else
 		msm_clock_init(&msm8910_clock_init_data);
-
-	if (socinfo_init() < 0)
-		pr_err("%s: socinfo_init() failed\n", __func__);
-
 	of_platform_populate(NULL, of_default_bus_match_table, adata, NULL);
 }
 
diff --git a/arch/arm/mach-msm/board-8930-pmic.c b/arch/arm/mach-msm/board-8930-pmic.c
index a5fded4..c0402ef 100644
--- a/arch/arm/mach-msm/board-8930-pmic.c
+++ b/arch/arm/mach-msm/board-8930-pmic.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
@@ -182,6 +182,8 @@
 static struct pm8xxx_mpp_init pm8917_mpps[] __initdata = {
 	PM8917_MPP_INIT(PM8XXX_AMUX_MPP_3, A_INPUT,
 				PM8XXX_MPP_AIN_AMUX_CH8, DIN_TO_INT),
+	/* Configure MPP01 for USB ID detection */
+	PM8917_MPP_INIT(1, D_INPUT, PM8921_MPP_DIG_LEVEL_S4, DIN_TO_INT),
 };
 
 void __init msm8930_pm8038_gpio_mpp_init(void)
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 3785fb2..b571304 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -10,6 +10,7 @@
  * GNU General Public License for more details.
  *
  */
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
@@ -1464,8 +1465,9 @@
 	msm_shared_ram_phys = MSM_SHARED_RAM_PHYS;
 	msm_map_msm8930_io();
 
-	if (socinfo_init() < 0)
+	if (IS_ERR_OR_NULL(socinfo_init()))
 		pr_err("socinfo_init() failed!\n");
+
 }
 
 static void __init msm8930_init_irq(void)
@@ -1558,7 +1560,6 @@
 	.mode			= USB_OTG,
 	.otg_control		= OTG_PMIC_CONTROL,
 	.phy_type		= SNPS_28NM_INTEGRATED_PHY,
-	.pmic_id_irq		= PM8038_USB_ID_IN_IRQ(PM8038_IRQ_BASE),
 	.power_budget		= 750,
 #ifdef CONFIG_MSM_BUS_SCALING
 	.bus_scale_table	= &usb_bus_scale_pdata,
@@ -2870,6 +2871,16 @@
 		msm_clock_init(&msm8930_pm8917_clock_init_data);
 	else
 		msm_clock_init(&msm8930_clock_init_data);
+
+	if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917) {
+		/* MPP01 IRQ number */
+		msm_otg_pdata.pmic_id_irq =
+				PM8921_MPP_IRQ(PM8917_IRQ_BASE, 1);
+	} else {
+		msm_otg_pdata.pmic_id_irq =
+				PM8038_USB_ID_IN_IRQ(PM8038_IRQ_BASE);
+	}
+
 	msm_otg_pdata.phy_init_seq = hsusb_phy_init_seq;
 	if (msm8930_mhl_display_enabled()) {
 		mhl_platform_data.mhl_enabled = true;
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index f64bf18..f4e7880 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -10,6 +10,7 @@
  * GNU General Public License for more details.
  *
  */
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
@@ -1486,9 +1487,9 @@
 {
 	msm_shared_ram_phys = MSM_SHARED_RAM_PHYS;
 	msm_map_msm8960_io();
-
-	if (socinfo_init() < 0)
+	if (IS_ERR_OR_NULL(socinfo_init()))
 		pr_err("socinfo_init() failed!\n");
+
 }
 
 static void __init msm8960_init_irq(void)
diff --git a/arch/arm/mach-msm/board-8974.c b/arch/arm/mach-msm/board-8974.c
index 2f6d3d0..b90d75b 100644
--- a/arch/arm/mach-msm/board-8974.c
+++ b/arch/arm/mach-msm/board-8974.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
@@ -10,6 +10,7 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
@@ -358,18 +359,20 @@
 static void __init msm8974_map_io(void)
 {
 	msm_map_8974_io();
-	if (socinfo_init() < 0)
-		pr_err("%s: socinfo_init() failed\n", __func__);
 }
 
 void __init msm8974_init(void)
 {
 	struct of_dev_auxdata *adata = msm8974_auxdata_lookup;
+	struct device *parent;
+
+	parent = socinfo_init();
+	if (IS_ERR_OR_NULL(parent))
+		pr_err("%s: socinfo_init() failed\n", __func__);
 
 	msm_8974_init_gpiomux();
 	regulator_has_full_constraints();
 	of_platform_populate(NULL, of_default_bus_match_table, adata, NULL);
-
 	msm8974_add_drivers();
 }
 
diff --git a/arch/arm/mach-msm/board-9625-gpiomux.c b/arch/arm/mach-msm/board-9625-gpiomux.c
index 4465440..2f75470 100644
--- a/arch/arm/mach-msm/board-9625-gpiomux.c
+++ b/arch/arm/mach-msm/board-9625-gpiomux.c
@@ -142,6 +142,34 @@
 		},
 	},
 	{
+		.gpio	= 16,		/* Sec mi2s ws */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &mi2s_suspend_cfg,
+			[GPIOMUX_ACTIVE] = &mi2s_active_cfg,
+		},
+	},
+	{
+		.gpio	= 17,		/* Sec mi2s din */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &mi2s_suspend_cfg,
+			[GPIOMUX_ACTIVE] = &mi2s_active_cfg,
+		},
+	},
+	{
+		.gpio	= 18,		/* Sec mi2s dout */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &mi2s_suspend_cfg,
+			[GPIOMUX_ACTIVE] = &mi2s_active_cfg,
+		},
+	},
+	{
+		.gpio	= 19,		/* Sec mi2s clk */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &mi2s_suspend_cfg,
+			[GPIOMUX_ACTIVE] = &mi2s_active_cfg,
+		},
+	},
+	{
 		.gpio	= 71,		/* mi2s mclk */
 		.settings = {
 			[GPIOMUX_SUSPENDED] = &mi2s_suspend_cfg,
diff --git a/arch/arm/mach-msm/board-9625.c b/arch/arm/mach-msm/board-9625.c
index f6a354f..07c37dd 100644
--- a/arch/arm/mach-msm/board-9625.c
+++ b/arch/arm/mach-msm/board-9625.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
@@ -10,6 +10,7 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
@@ -236,7 +237,10 @@
 
 void __init msm9625_init(void)
 {
-	if (socinfo_init() < 0)
+	struct device *parent;
+
+	parent = socinfo_init();
+	if (IS_ERR_OR_NULL(parent))
 		pr_err("%s: socinfo_init() failed\n", __func__);
 
 	msm9625_init_gpiomux();
diff --git a/arch/arm/mach-msm/board-fsm9xxx.c b/arch/arm/mach-msm/board-fsm9xxx.c
index 274b338..16740b2 100644
--- a/arch/arm/mach-msm/board-fsm9xxx.c
+++ b/arch/arm/mach-msm/board-fsm9xxx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -1002,10 +1002,8 @@
 {
 	msm_shared_ram_phys = 0x00100000;
 	msm_map_fsm9xxx_io();
-	if (socinfo_init() < 0)
-		pr_err("%s: socinfo_init() failed!\n",
-		       __func__);
-
+	if (IS_ERR_OR_NULL(socinfo_init()))
+		pr_err("socinfo_init() failed!\n");
 }
 
 MACHINE_START(FSM9XXX_SURF, "QCT FSM9XXX")
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index 9822aa9..752c99a 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.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
@@ -11,6 +11,7 @@
  *
  */
 
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/irq.h>
 #include <linux/gpio.h>
@@ -7348,9 +7349,8 @@
 {
 	msm_shared_ram_phys = 0x00100000;
 	msm_map_msm7x30_io();
-	if (socinfo_init() < 0)
-		printk(KERN_ERR "%s: socinfo_init() failed!\n",
-		       __func__);
+	if (IS_ERR_OR_NULL(socinfo_init()))
+		pr_err("socinfo_init() failed!\n");
 }
 
 static void __init msm7x30_init_early(void)
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index d4205bd..e678dfb 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.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
@@ -11,6 +11,7 @@
  *
  */
 
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/gpio.h>
@@ -7540,9 +7541,9 @@
 {
 	msm_shared_ram_phys = MSM_SHARED_RAM_PHYS;
 	msm_map_msm8x60_io();
-
-	if (socinfo_init() < 0)
+	if (IS_ERR_OR_NULL(socinfo_init()))
 		pr_err("socinfo_init() failed!\n");
+
 }
 
 /*
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c
index 146c8a8..57c548e 100644
--- a/arch/arm/mach-msm/board-qsd8x50.c
+++ b/arch/arm/mach-msm/board-qsd8x50.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
@@ -2521,9 +2521,8 @@
 	msm_shared_ram_phys = MSM_SHARED_RAM_PHYS;
 	msm_map_qsd8x50_io();
 	qsd8x50_allocate_memory_regions();
-	if (socinfo_init() < 0)
-		printk(KERN_ERR "%s: socinfo_init() failed!\n",
-		       __func__);
+	if (IS_ERR_OR_NULL(socinfo_init()))
+		pr_err("socinfo_init() failed!\n");
 }
 
 MACHINE_START(QSD8X50_SURF, "QCT QSD8X50 SURF")
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 1b0ac74..43a03a0 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.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
@@ -5281,6 +5281,7 @@
 						"fda64000.qcom,iommu"),
 	CLK_LOOKUP("core_clk", camss_jpeg_jpeg_axi_clk.c,
 						"fda64000.qcom,iommu"),
+	CLK_LOOKUP("alt_core_clk", camss_top_ahb_clk.c, "fda64000.qcom,iommu"),
 	CLK_LOOKUP("bus_clk0", camss_jpeg_jpeg_axi_clk.c, "fda1c000.qcom,jpeg"),
 	CLK_LOOKUP("bus_clk0", camss_jpeg_jpeg_axi_clk.c, "fda20000.qcom,jpeg"),
 	CLK_LOOKUP("bus_clk0", camss_jpeg_jpeg_axi_clk.c, "fda24000.qcom,jpeg"),
@@ -5297,8 +5298,9 @@
 	CLK_LOOKUP("camss_top_ahb_clk", camss_top_ahb_clk.c,
 						"fda24000.qcom,jpeg"),
 	CLK_LOOKUP("iface_clk", camss_micro_ahb_clk.c, ""),
-	CLK_LOOKUP("iface_clk", camss_vfe_cpp_ahb_clk.c, "fda44000.qcom,iommu"),
-	CLK_LOOKUP("core_clk", camss_vfe_cpp_clk.c, "fda44000.qcom,iommu"),
+	CLK_LOOKUP("iface_clk", camss_vfe_vfe_ahb_clk.c, "fda44000.qcom,iommu"),
+	CLK_LOOKUP("core_clk", camss_vfe_vfe_axi_clk.c, "fda44000.qcom,iommu"),
+	CLK_LOOKUP("alt_core_clk", camss_top_ahb_clk.c, "fda44000.qcom,iommu"),
 	CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "mdp.0"),
 	CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "mdss_dsi_clk_ctrl"),
 	CLK_LOOKUP("iface_clk", mdss_ahb_clk.c, "fd923400.qcom,mdss_edp"),
@@ -5451,56 +5453,6 @@
 	CLK_LOOKUP("krait3_m_clk",	krait3_m_clk, ""),
 };
 
-static struct pll_config_regs gpll0_regs __initdata = {
-	.l_reg = (void __iomem *)GPLL0_L_REG,
-	.m_reg = (void __iomem *)GPLL0_M_REG,
-	.n_reg = (void __iomem *)GPLL0_N_REG,
-	.config_reg = (void __iomem *)GPLL0_USER_CTL_REG,
-	.mode_reg = (void __iomem *)GPLL0_MODE_REG,
-	.base = &virt_bases[GCC_BASE],
-};
-
-/* GPLL0 at 600 MHz, main output enabled. */
-static struct pll_config gpll0_config __initdata = {
-	.l = 0x1f,
-	.m = 0x1,
-	.n = 0x4,
-	.vco_val = 0x0,
-	.vco_mask = BM(21, 20),
-	.pre_div_val = 0x0,
-	.pre_div_mask = BM(14, 12),
-	.post_div_val = 0x0,
-	.post_div_mask = BM(9, 8),
-	.mn_ena_val = BIT(24),
-	.mn_ena_mask = BIT(24),
-	.main_output_val = BIT(0),
-	.main_output_mask = BIT(0),
-};
-
-static struct pll_config_regs gpll1_regs __initdata = {
-	.l_reg = (void __iomem *)GPLL1_L_REG,
-	.m_reg = (void __iomem *)GPLL1_M_REG,
-	.n_reg = (void __iomem *)GPLL1_N_REG,
-	.config_reg = (void __iomem *)GPLL1_USER_CTL_REG,
-	.mode_reg = (void __iomem *)GPLL1_MODE_REG,
-	.base = &virt_bases[GCC_BASE],
-};
-
-/* GPLL1 at 480 MHz, main output enabled. */
-static struct pll_config gpll1_config __initdata = {
-	.l = 0x19,
-	.m = 0x0,
-	.n = 0x1,
-	.vco_val = 0x0,
-	.vco_mask = BM(21, 20),
-	.pre_div_val = 0x0,
-	.pre_div_mask = BM(14, 12),
-	.post_div_val = 0x0,
-	.post_div_mask = BM(9, 8),
-	.main_output_val = BIT(0),
-	.main_output_mask = BIT(0),
-};
-
 static struct pll_config_regs mmpll0_regs __initdata = {
 	.l_reg = (void __iomem *)MMPLL0_L_REG,
 	.m_reg = (void __iomem *)MMPLL0_M_REG,
@@ -5605,9 +5557,6 @@
 	.main_output_mask = BIT(0),
 };
 
-#define PLL_AUX_OUTPUT_BIT 1
-#define PLL_AUX2_OUTPUT_BIT 2
-
 #define PWR_ON_MASK		BIT(31)
 #define EN_REST_WAIT_MASK	(0xF << 20)
 #define EN_FEW_WAIT_MASK	(0xF << 16)
@@ -5627,24 +5576,11 @@
 	u32 regval, status;
 	int ret;
 
-	if (!(readl_relaxed(GCC_REG_BASE(GPLL0_STATUS_REG))
-			& gpll0_clk_src.status_mask))
-		configure_sr_hpm_lp_pll(&gpll0_config, &gpll0_regs, 1);
-
-	if (!(readl_relaxed(GCC_REG_BASE(GPLL1_STATUS_REG))
-			& gpll1_clk_src.status_mask))
-		configure_sr_hpm_lp_pll(&gpll1_config, &gpll1_regs, 1);
-
 	configure_sr_hpm_lp_pll(&mmpll0_config, &mmpll0_regs, 1);
 	configure_sr_hpm_lp_pll(&mmpll1_config, &mmpll1_regs, 1);
 	configure_sr_hpm_lp_pll(&mmpll3_config, &mmpll3_regs, 0);
 	configure_sr_hpm_lp_pll(&lpapll0_config, &lpapll0_regs, 1);
 
-	/* Enable GPLL0's aux outputs. */
-	regval = readl_relaxed(GCC_REG_BASE(GPLL0_USER_CTL_REG));
-	regval |= BIT(PLL_AUX_OUTPUT_BIT) | BIT(PLL_AUX2_OUTPUT_BIT);
-	writel_relaxed(regval, GCC_REG_BASE(GPLL0_USER_CTL_REG));
-
 	/* Vote for GPLL0 to turn on. Needed by acpuclock. */
 	regval = readl_relaxed(GCC_REG_BASE(APCS_GPLL_ENA_VOTE_REG));
 	regval |= BIT(0);
diff --git a/arch/arm/mach-msm/clock-9625.c b/arch/arm/mach-msm/clock-9625.c
index f4c045c..151f192 100644
--- a/arch/arm/mach-msm/clock-9625.c
+++ b/arch/arm/mach-msm/clock-9625.c
@@ -2125,10 +2125,14 @@
 		   "msm-dai-q6-mi2s.0"),
 	CLK_LOOKUP("ibit_clk", audio_core_lpaif_pri_ibit_clk.c,
 		   "msm-dai-q6-mi2s.0"),
-	CLK_LOOKUP("core_clk", audio_core_lpaif_sec_clk_src.c, ""),
-	CLK_LOOKUP("osr_clk", audio_core_lpaif_sec_osr_clk.c, ""),
-	CLK_LOOKUP("ebit_clk", audio_core_lpaif_sec_ebit_clk.c, ""),
-	CLK_LOOKUP("ibit_clk", audio_core_lpaif_sec_ibit_clk.c, ""),
+	CLK_LOOKUP("core_clk", audio_core_lpaif_sec_clk_src.c,
+		   "msm-dai-q6-mi2s.1"),
+	CLK_LOOKUP("osr_clk", audio_core_lpaif_sec_osr_clk.c,
+		   "msm-dai-q6-mi2s.1"),
+	CLK_LOOKUP("ebit_clk", audio_core_lpaif_sec_ebit_clk.c,
+		   "msm-dai-q6-mi2s.1"),
+	CLK_LOOKUP("ibit_clk", audio_core_lpaif_sec_ibit_clk.c,
+		   "msm-dai-q6-mi2s.1"),
 	CLK_LOOKUP("core_clk", audio_core_lpaif_pcm0_clk_src.c, ""),
 	CLK_LOOKUP("ebit_clk", audio_core_lpaif_pcm0_ebit_clk.c, ""),
 	CLK_LOOKUP("ibit_clk", audio_core_lpaif_pcm0_ibit_clk.c, ""),
diff --git a/arch/arm/mach-msm/devices-9615.c b/arch/arm/mach-msm/devices-9615.c
index cec57fd..15994565 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -11,6 +11,7 @@
  *
  */
 
+#include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/irq.h>
@@ -1545,7 +1546,7 @@
 	msm_shared_ram_phys = MSM_SHARED_RAM_PHYS;
 	msm_map_msm9615_io();
 	l2x0_cache_init();
-	if (socinfo_init() < 0)
+	if (IS_ERR_OR_NULL(socinfo_init()))
 		pr_err("socinfo_init() failed!\n");
 }
 
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 3c60fa6..c8b160c 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.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
@@ -2147,8 +2147,8 @@
 void __init msm_common_io_init(void)
 {
 	msm_map_common_io();
-	if (socinfo_init() < 0)
-		pr_err("%s: socinfo_init() failed!\n", __func__);
+	if (IS_ERR_OR_NULL(socinfo_init()))
+		pr_err("socinfo_init() failed!\n");
 	msm7x27x_cache_init();
 }
 
@@ -2163,8 +2163,8 @@
 {
 	msm_map_msm8625_io();
 
-	if (socinfo_init() < 0)
-		pr_err("%s: socinfo_init() failed!\n", __func__);
+	if (IS_ERR_OR_NULL(socinfo_init()))
+		pr_err("socinfo_init() failed!\n");
 	msm7x27x_cache_init();
 }
 
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/audio_acdb_def.h b/arch/arm/mach-msm/include/mach/qdsp5/audio_acdb_def.h
index e1fc0cd..5fc87e0 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/audio_acdb_def.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/audio_acdb_def.h
@@ -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
@@ -48,4 +48,5 @@
 /* ID used for virtual devices */
 #define PSEUDO_ACDB_ID					0xFFFF
 
+int is_acdb_enabled(void);
 #endif /* _MACH_QDSP5_V2_AUDIO_ACDB_DEF_H */
diff --git a/arch/arm/mach-msm/include/mach/socinfo.h b/arch/arm/mach-msm/include/mach/socinfo.h
index c0624bb..345f09c 100644
--- a/arch/arm/mach-msm/include/mach/socinfo.h
+++ b/arch/arm/mach-msm/include/mach/socinfo.h
@@ -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
@@ -147,7 +147,7 @@
 uint32_t socinfo_get_platform_version(void);
 enum pmic_model socinfo_get_pmic_model(void);
 uint32_t socinfo_get_pmic_die_revision(void);
-int __init socinfo_init(void) __must_check;
+struct device * __init socinfo_init(void) __must_check;
 const int read_msm_cpu_type(void);
 const int get_core_count(void);
 const int cpu_is_krait(void);
diff --git a/arch/arm/mach-msm/kernel_test_service_v01.c b/arch/arm/mach-msm/kernel_test_service_v01.c
new file mode 100644
index 0000000..498e046
--- /dev/null
+++ b/arch/arm/mach-msm/kernel_test_service_v01.c
@@ -0,0 +1,254 @@
+/* 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 <linux/qmi_encdec.h>
+
+#include <mach/msm_qmi_interface.h>
+
+#include "kernel_test_service_v01.h"
+
+#define PING_REQ1_TLV_TYPE 0x1
+#define PING_RESP1_TLV_TYPE 0x2
+#define PING_OPT1_TLV_TYPE 0x10
+#define PING_OPT2_TLV_TYPE 0x11
+
+#define DATA_REQ1_TLV_TYPE 0x1
+#define DATA_RESP1_TLV_TYPE 0x2
+#define DATA_OPT1_TLV_TYPE 0x10
+#define DATA_OPT2_TLV_TYPE 0x11
+
+static struct elem_info test_name_type_v01_ei[] = {
+	{
+		.data_type      = QMI_DATA_LEN,
+		.elem_len	= 1,
+		.elem_size      = sizeof(uint8_t),
+		.is_array	= NO_ARRAY,
+		.tlv_type	= QMI_COMMON_TLV_TYPE,
+		.offset		= offsetof(struct test_name_type_v01,
+					   name_len),
+	},
+	{
+		.data_type      = QMI_UNSIGNED_1_BYTE,
+		.elem_len       = TEST_MAX_NAME_SIZE_V01,
+		.elem_size      = sizeof(char),
+		.is_array       = VAR_LEN_ARRAY,
+		.tlv_type       = QMI_COMMON_TLV_TYPE,
+		.offset         = offsetof(struct test_name_type_v01,
+					   name),
+	},
+	{
+		.data_type      = QMI_EOTI,
+		.is_array       = NO_ARRAY,
+		.tlv_type       = QMI_COMMON_TLV_TYPE,
+	},
+};
+
+struct elem_info test_ping_req_msg_v01_ei[] = {
+	{
+		.data_type      = QMI_UNSIGNED_1_BYTE,
+		.elem_len       = 4,
+		.elem_size      = sizeof(char),
+		.is_array       = STATIC_ARRAY,
+		.tlv_type       = PING_REQ1_TLV_TYPE,
+		.offset         = offsetof(struct test_ping_req_msg_v01,
+					   ping),
+	},
+	{
+		.data_type      = QMI_OPT_FLAG,
+		.elem_len       = 1,
+		.elem_size      = sizeof(uint8_t),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = PING_OPT1_TLV_TYPE,
+		.offset         = offsetof(struct test_ping_req_msg_v01,
+					   client_name_valid),
+	},
+	{
+		.data_type      = QMI_STRUCT,
+		.elem_len       = 1,
+		.elem_size      = sizeof(struct test_name_type_v01),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = PING_OPT1_TLV_TYPE,
+		.offset         = offsetof(struct test_ping_req_msg_v01,
+					   client_name),
+		.ei_array       = test_name_type_v01_ei,
+	},
+	{
+		.data_type      = QMI_EOTI,
+		.is_array       = NO_ARRAY,
+		.tlv_type       = QMI_COMMON_TLV_TYPE,
+	},
+};
+
+struct elem_info test_ping_resp_msg_v01_ei[] = {
+	{
+		.data_type      = QMI_STRUCT,
+		.elem_len       = 1,
+		.elem_size      = sizeof(struct qmi_response_type_v01),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = PING_RESP1_TLV_TYPE,
+		.offset         = offsetof(struct test_ping_resp_msg_v01,
+					   resp),
+		.ei_array       = get_qmi_response_type_v01_ei(),
+	},
+	{
+		.data_type      = QMI_OPT_FLAG,
+		.elem_len       = 1,
+		.elem_size      = sizeof(uint8_t),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = PING_OPT1_TLV_TYPE,
+		.offset         = offsetof(struct test_ping_resp_msg_v01,
+					   pong_valid),
+	},
+	{
+		.data_type      = QMI_UNSIGNED_1_BYTE,
+		.elem_len       = 4,
+		.elem_size      = sizeof(char),
+		.is_array       = STATIC_ARRAY,
+		.tlv_type       = PING_OPT1_TLV_TYPE,
+		.offset         = offsetof(struct test_ping_resp_msg_v01,
+					   pong),
+	},
+	{
+		.data_type      = QMI_OPT_FLAG,
+		.elem_len       = 1,
+		.elem_size      = sizeof(uint8_t),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = PING_OPT2_TLV_TYPE,
+		.offset         = offsetof(struct test_ping_resp_msg_v01,
+					   service_name_valid),
+	},
+	{
+		.data_type      = QMI_STRUCT,
+		.elem_len       = 1,
+		.elem_size      = sizeof(struct test_name_type_v01),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = PING_OPT2_TLV_TYPE,
+		.offset         = offsetof(struct test_ping_resp_msg_v01,
+					   service_name),
+		.ei_array       = test_name_type_v01_ei,
+	},
+	{
+		.data_type      = QMI_EOTI,
+		.is_array       = NO_ARRAY,
+		.tlv_type       = QMI_COMMON_TLV_TYPE,
+	},
+};
+
+struct elem_info test_data_req_msg_v01_ei[] = {
+	{
+		.data_type      = QMI_DATA_LEN,
+		.elem_len       = 1,
+		.elem_size      = sizeof(uint32_t),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = DATA_REQ1_TLV_TYPE,
+		.offset         = offsetof(struct test_data_req_msg_v01,
+					   data_len),
+	},
+	{
+		.data_type      = QMI_UNSIGNED_1_BYTE,
+		.elem_len       = TEST_MED_DATA_SIZE_V01,
+		.elem_size      = sizeof(uint8_t),
+		.is_array       = VAR_LEN_ARRAY,
+		.tlv_type       = DATA_REQ1_TLV_TYPE,
+		.offset         = offsetof(struct test_data_req_msg_v01,
+					   data),
+	},
+	{
+		.data_type      = QMI_OPT_FLAG,
+		.elem_len       = 1,
+		.elem_size      = sizeof(uint8_t),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = DATA_OPT1_TLV_TYPE,
+		.offset         = offsetof(struct test_data_req_msg_v01,
+					   client_name_valid),
+	},
+	{
+		.data_type      = QMI_STRUCT,
+		.elem_len       = 1,
+		.elem_size      = sizeof(struct test_name_type_v01),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = DATA_OPT1_TLV_TYPE,
+		.offset         = offsetof(struct test_data_req_msg_v01,
+					   client_name),
+		.ei_array       = test_name_type_v01_ei,
+	},
+	{
+		.data_type      = QMI_EOTI,
+		.is_array       = NO_ARRAY,
+		.tlv_type       = QMI_COMMON_TLV_TYPE,
+	},
+};
+
+struct elem_info test_data_resp_msg_v01_ei[] = {
+	{
+		.data_type      = QMI_STRUCT,
+		.elem_len       = 1,
+		.elem_size      = sizeof(struct qmi_response_type_v01),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = DATA_RESP1_TLV_TYPE,
+		.offset         = offsetof(struct test_data_resp_msg_v01,
+					   resp),
+		.ei_array       = get_qmi_response_type_v01_ei(),
+	},
+	{
+		.data_type      = QMI_OPT_FLAG,
+		.elem_len       = 1,
+		.elem_size      = sizeof(uint8_t),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = DATA_OPT1_TLV_TYPE,
+		.offset         = offsetof(struct test_data_resp_msg_v01,
+					   data_valid),
+	},
+	{
+		.data_type      = QMI_DATA_LEN,
+		.elem_len       = 1,
+		.elem_size      = sizeof(uint32_t),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = DATA_OPT1_TLV_TYPE,
+		.offset         = offsetof(struct test_data_resp_msg_v01,
+					   data_len),
+	},
+	{
+		.data_type      = QMI_UNSIGNED_1_BYTE,
+		.elem_len       = TEST_MED_DATA_SIZE_V01,
+		.elem_size      = sizeof(uint8_t),
+		.is_array       = VAR_LEN_ARRAY,
+		.tlv_type       = DATA_OPT1_TLV_TYPE,
+		.offset         = offsetof(struct test_data_resp_msg_v01,
+					   data),
+	},
+	{
+		.data_type      = QMI_OPT_FLAG,
+		.elem_len       = 1,
+		.elem_size      = sizeof(uint8_t),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = DATA_OPT2_TLV_TYPE,
+		.offset         = offsetof(struct test_data_resp_msg_v01,
+					   service_name_valid),
+	},
+	{
+		.data_type      = QMI_STRUCT,
+		.elem_len       = 1,
+		.elem_size      = sizeof(struct test_name_type_v01),
+		.is_array       = NO_ARRAY,
+		.tlv_type       = DATA_OPT2_TLV_TYPE,
+		.offset         = offsetof(struct test_data_resp_msg_v01,
+					   service_name),
+		.ei_array       = test_name_type_v01_ei,
+	},
+	{
+		.data_type      = QMI_EOTI,
+		.is_array       = NO_ARRAY,
+		.tlv_type       = QMI_COMMON_TLV_TYPE,
+	},
+};
diff --git a/arch/arm/mach-msm/kernel_test_service_v01.h b/arch/arm/mach-msm/kernel_test_service_v01.h
new file mode 100644
index 0000000..79c1845
--- /dev/null
+++ b/arch/arm/mach-msm/kernel_test_service_v01.h
@@ -0,0 +1,73 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef MSM_QMI_TEST_SERVICE_V01_H
+#define MSM_QMI_TEST_SERVICE_V01_H
+
+#include <mach/msm_qmi_interface.h>
+
+#define TEST_MED_DATA_SIZE_V01 8192
+#define TEST_MAX_NAME_SIZE_V01 255
+
+#define TEST_PING_REQ_MSG_ID_V01 0x20
+#define TEST_DATA_REQ_MSG_ID_V01 0x21
+
+#define TEST_PING_REQ_MAX_MSG_LEN_V01 266
+#define TEST_DATA_REQ_MAX_MSG_LEN_V01 8456
+
+struct test_name_type_v01 {
+	uint32_t name_len;
+	char name[TEST_MAX_NAME_SIZE_V01];
+};
+
+struct test_ping_req_msg_v01 {
+	char ping[4];
+
+	uint8_t client_name_valid;
+	struct test_name_type_v01 client_name;
+};
+
+struct test_ping_resp_msg_v01 {
+	struct qmi_response_type_v01 resp;
+
+	uint8_t pong_valid;
+	char pong[4];
+
+	uint8_t service_name_valid;
+	struct test_name_type_v01 service_name;
+};
+
+struct test_data_req_msg_v01 {
+	uint32_t data_len;
+	uint8_t data[TEST_MED_DATA_SIZE_V01];
+
+	uint8_t client_name_valid;
+	struct test_name_type_v01 client_name;
+};
+
+struct test_data_resp_msg_v01 {
+	struct qmi_response_type_v01 resp;
+
+	uint8_t data_valid;
+	uint32_t data_len;
+	uint8_t data[TEST_MED_DATA_SIZE_V01];
+
+	uint8_t service_name_valid;
+	struct test_name_type_v01 service_name;
+};
+
+extern struct elem_info test_ping_req_msg_v01_ei[];
+extern struct elem_info test_data_req_msg_v01_ei[];
+extern struct elem_info test_ping_resp_msg_v01_ei[];
+extern struct elem_info test_data_resp_msg_v01_ei[];
+
+#endif
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c b/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
index b6870c6..2c4b434 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -679,7 +679,7 @@
 	return ret;
 }
 
-static int msm_bus_fabric_probe(struct platform_device *pdev)
+static int __devinit msm_bus_fabric_probe(struct platform_device *pdev)
 {
 	int ctx, ret = 0;
 	struct msm_bus_fabric *fabric;
@@ -694,7 +694,6 @@
 	INIT_LIST_HEAD(&fabric->gateways);
 	INIT_RADIX_TREE(&fabric->fab_tree, GFP_ATOMIC);
 	fabric->num_nodes = 0;
-	fabric->fabdev.id = pdev->id;
 	fabric->fabdev.visited = false;
 
 	fabric->info.node_info = kzalloc(sizeof(struct msm_bus_node_info),
@@ -704,18 +703,31 @@
 		kfree(fabric);
 		return -ENOMEM;
 	}
-	fabric->info.node_info->priv_id = fabric->fabdev.id;
-	fabric->info.node_info->id = fabric->fabdev.id;
+
 	fabric->info.num_pnodes = -1;
 	fabric->info.link_info.clk[DUAL_CTX] = 0;
 	fabric->info.link_info.bw[DUAL_CTX] = 0;
 	fabric->info.link_info.clk[ACTIVE_CTX] = 0;
 	fabric->info.link_info.bw[ACTIVE_CTX] = 0;
 
-	fabric->fabdev.id = pdev->id;
-	pdata = (struct msm_bus_fabric_registration *)pdev->dev.platform_data;
+	/* If possible, get pdata from device-tree */
+	if (pdev->dev.of_node) {
+		pdata = pdev->dev.platform_data;
+		if (IS_ERR(pdata) || ZERO_OR_NULL_PTR(pdata)) {
+			pr_err("Null platform data\n");
+			return PTR_ERR(pdata);
+		}
+		fabric->fabdev.id = pdata->id;
+	} else {
+		pdata = (struct msm_bus_fabric_registration *)pdev->
+			dev.platform_data;
+		fabric->fabdev.id = pdev->id;
+	}
+
 	fabric->fabdev.name = pdata->name;
 	fabric->fabdev.algo = &msm_bus_algo;
+	fabric->info.node_info->priv_id = fabric->fabdev.id;
+	fabric->info.node_info->id = fabric->fabdev.id;
 	ret = msm_bus_fabric_hw_init(pdata, &fabric->fabdev.hw_algo);
 	if (ret) {
 		MSM_BUS_ERR("Error initializing hardware for fabric: %d\n",
@@ -811,12 +823,18 @@
 	return ret;
 }
 
+static struct of_device_id fabric_match[] = {
+	{.compatible = "msm_bus_fabric"},
+	{}
+};
+
 static struct platform_driver msm_bus_fabric_driver = {
 	.probe = msm_bus_fabric_probe,
 	.remove = msm_bus_fabric_remove,
 	.driver = {
 		.name = "msm_bus_fabric",
 		.owner = THIS_MODULE,
+		.of_match_table = fabric_match,
 	},
 };
 
@@ -825,4 +843,4 @@
 	MSM_BUS_ERR("msm_bus_fabric_init_driver\n");
 	return platform_driver_register(&msm_bus_fabric_driver);
 }
-postcore_initcall(msm_bus_fabric_init_driver);
+subsys_initcall(msm_bus_fabric_init_driver);
diff --git a/arch/arm/mach-msm/msm_watchdog_v2.c b/arch/arm/mach-msm/msm_watchdog_v2.c
index 2a4422e..6aa14a6 100644
--- a/arch/arm/mach-msm/msm_watchdog_v2.c
+++ b/arch/arm/mach-msm/msm_watchdog_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
@@ -41,6 +41,8 @@
 #define SCM_SET_REGSAVE_CMD	0x2
 #define SCM_SVC_SEC_WDOG_DIS	0x7
 
+static struct workqueue_struct *wdog_wq;
+
 struct msm_watchdog_data {
 	unsigned int __iomem phys_base;
 	size_t size;
@@ -213,7 +215,7 @@
 		work_data.wdog_dd = wdog_dd;
 		init_completion(&work_data.complete);
 		INIT_WORK_ONSTACK(&work_data.work, wdog_disable_work);
-		schedule_work_on(0, &work_data.work);
+		queue_work_on(0, wdog_wq, &work_data.work);
 		wait_for_completion(&work_data.complete);
 		mutex_unlock(&wdog_dd->disable_lock);
 	} else {
@@ -288,8 +290,8 @@
 	/* Check again before scheduling *
 	 * Could have been changed on other cpu */
 	if (enable)
-		schedule_delayed_work_on(0, &wdog_dd->dogwork_struct,
-							delay_time);
+		queue_delayed_work_on(0, wdog_wq,
+				&wdog_dd->dogwork_struct, delay_time);
 }
 
 static int msm_watchdog_remove(struct platform_device *pdev)
@@ -303,7 +305,7 @@
 		work_data.wdog_dd = wdog_dd;
 		init_completion(&work_data.complete);
 		INIT_WORK_ONSTACK(&work_data.work, wdog_disable_work);
-		schedule_work_on(0, &work_data.work);
+		queue_work_on(0, wdog_wq, &work_data.work);
 		wait_for_completion(&work_data.complete);
 	}
 	mutex_unlock(&wdog_dd->disable_lock);
@@ -311,6 +313,7 @@
 	if (wdog_dd->irq_ppi)
 		free_percpu(wdog_dd->wdog_cpu_dd);
 	printk(KERN_INFO "MSM Watchdog Exit - Deactivated\n");
+	destroy_workqueue(wdog_wq);
 	kfree(wdog_dd);
 	return 0;
 }
@@ -425,7 +428,8 @@
 	atomic_notifier_chain_register(&panic_notifier_list,
 				       &wdog_dd->panic_blk);
 	mutex_init(&wdog_dd->disable_lock);
-	schedule_delayed_work_on(0, &wdog_dd->dogwork_struct, delay_time);
+	queue_delayed_work_on(0, wdog_wq, &wdog_dd->dogwork_struct,
+			delay_time);
 	__raw_writel(1, wdog_dd->base + WDT0_EN);
 	__raw_writel(1, wdog_dd->base + WDT0_RST);
 	wdog_dd->last_pet = sched_clock();
@@ -509,6 +513,12 @@
 	int ret;
 	struct msm_watchdog_data *wdog_dd;
 
+	wdog_wq = alloc_workqueue("wdog", WQ_HIGHPRI, 0);
+	if (!wdog_wq) {
+		pr_err("Failed to allocate watchdog workqueue\n");
+		return -EIO;
+	}
+
 	if (!pdev->dev.of_node || !enable)
 		return -ENODEV;
 	wdog_dd = kzalloc(sizeof(struct msm_watchdog_data), GFP_KERNEL);
@@ -522,9 +532,10 @@
 	cpumask_clear(&wdog_dd->alive_mask);
 	INIT_WORK(&wdog_dd->init_dogwork_struct, init_watchdog_work);
 	INIT_DELAYED_WORK(&wdog_dd->dogwork_struct, pet_watchdog_work);
-	schedule_work_on(0, &wdog_dd->init_dogwork_struct);
+	queue_work_on(0, wdog_wq, &wdog_dd->init_dogwork_struct);
 	return 0;
 err:
+	destroy_workqueue(wdog_wq);
 	kzfree(wdog_dd);
 	return ret;
 }
diff --git a/arch/arm/mach-msm/peripheral-loader.c b/arch/arm/mach-msm/peripheral-loader.c
index c903b72..affb451 100644
--- a/arch/arm/mach-msm/peripheral-loader.c
+++ b/arch/arm/mach-msm/peripheral-loader.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
@@ -680,7 +680,7 @@
 	struct pil_priv *priv;
 	int id;
 	void __iomem *addr;
-	size_t len;
+	char buf[sizeof(priv->info->name)];
 
 	/* Ignore users who don't make any sense */
 	WARN(desc->ops->proxy_unvote && !desc->proxy_timeout,
@@ -703,9 +703,8 @@
 	addr = PIL_IMAGE_INFO_BASE + sizeof(struct pil_image_info) * id;
 	priv->info = (struct pil_image_info __iomem *)addr;
 
-	len = min(strlen(desc->name), sizeof(priv->info->name));
-	memset_io(priv->info->name, 0, sizeof(priv->info->name));
-	memcpy_toio(priv->info->name, desc->name, len);
+	strncpy(buf, desc->name, sizeof(buf));
+	__iowrite32_copy(priv->info->name, buf, sizeof(buf) / 4);
 
 	snprintf(priv->wname, sizeof(priv->wname), "pil-%s", desc->name);
 	wake_lock_init(&priv->wlock, WAKE_LOCK_SUSPEND, priv->wname);
diff --git a/arch/arm/mach-msm/qdsp5/audio_acdb.c b/arch/arm/mach-msm/qdsp5/audio_acdb.c
index d7a4607..681b41c 100644
--- a/arch/arm/mach-msm/qdsp5/audio_acdb.c
+++ b/arch/arm/mach-msm/qdsp5/audio_acdb.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
@@ -1301,6 +1301,15 @@
 }
 EXPORT_SYMBOL(acdb_get_calibration_data);
 
+int is_acdb_enabled()
+{
+	if (acdb_data.handle != NULL)
+		return 1;
+	else
+		return 0;
+}
+EXPORT_SYMBOL(is_acdb_enabled);
+
 static u8 check_device_info_already_present(
 		struct dev_evt_msg device_info,
 			struct acdb_cache_node *acdb_cache_free_node)
@@ -1522,7 +1531,7 @@
 			result = -EINVAL;
 			goto done;
 		} else
-			MM_DBG("AUDPP is calibrated with IIR parameters");
+			MM_DBG("AUDPP is calibrated with IIR parameters\n");
 	}
 	result = acdb_fill_audpp_mbadrc();
 	if (!IS_ERR_VALUE(result)) {
@@ -2270,13 +2279,9 @@
 		if (ret == 1) {
 			MM_DBG("got device ready call back for another "\
 					"audplay task sessions on same COPP\n");
-			/*stream_id is used to keep track of number of active*/
-			/*sessions active on this device*/
-			acdb_cache_free_node->stream_id++;
 			mutex_unlock(&acdb_data.acdb_mutex);
 			goto done;
 		}
-		acdb_cache_free_node->stream_id++;
 	}
 	update_acdb_data_struct(acdb_cache_free_node);
 	acdb_data.device_cb_compl = 1;
@@ -2317,6 +2322,9 @@
 		}
 		goto done;
 	}
+	/*stream_id is used to keep track of number of active*/
+	/*sessions active on this device*/
+	acdb_cache_rx.stream_id++;
 
 	acdb_data.acdb_state |= AUDPP_READY;
 	acdb_data.audpp_cb_compl = 1;
diff --git a/arch/arm/mach-msm/qdsp5/audio_out.c b/arch/arm/mach-msm/qdsp5/audio_out.c
index 6f3bf91..fee7404 100644
--- a/arch/arm/mach-msm/qdsp5/audio_out.c
+++ b/arch/arm/mach-msm/qdsp5/audio_out.c
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2012 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -39,6 +39,7 @@
 
 #include "audmgr.h"
 
+#include <mach/qdsp5/audio_acdb_def.h>
 #include <mach/qdsp5/qdsp5audppcmdi.h>
 #include <mach/qdsp5/qdsp5audppmsg.h>
 #include <mach/qdsp5/qdsp5audpp.h>
@@ -298,19 +299,20 @@
 	if (!audio_copp->status)
 		return;
 
-	audpp_dsp_set_mbadrc(COMMON_OBJ_ID, audio_copp->mbadrc_enable,
+	if (!is_acdb_enabled()) {
+		audpp_dsp_set_mbadrc(COMMON_OBJ_ID, audio_copp->mbadrc_enable,
 						&audio_copp->mbadrc);
 
-	audpp_dsp_set_eq(COMMON_OBJ_ID, audio_copp->eq_enable,
+		audpp_dsp_set_eq(COMMON_OBJ_ID, audio_copp->eq_enable,
 						&audio_copp->eq);
-
-	audpp_dsp_set_rx_iir(COMMON_OBJ_ID, audio_copp->rx_iir_enable,
+		audpp_dsp_set_rx_iir(COMMON_OBJ_ID, audio_copp->rx_iir_enable,
 							&audio_copp->iir);
-	audpp_dsp_set_vol_pan(COMMON_OBJ_ID, &audio_copp->vol_pan);
+		audpp_dsp_set_vol_pan(COMMON_OBJ_ID, &audio_copp->vol_pan);
 
-	audpp_dsp_set_qconcert_plus(COMMON_OBJ_ID,
+		audpp_dsp_set_qconcert_plus(COMMON_OBJ_ID,
 				audio_copp->qconcert_plus_enable,
 				&audio_copp->qconcert_plus);
+	}
 	audio_enable_srs_trumedia(audio_copp, true);
 }
 EXPORT_SYMBOL(audio_commit_pending_pp_params);
diff --git a/arch/arm/mach-msm/qdsp5/audio_pcm_in.c b/arch/arm/mach-msm/qdsp5/audio_pcm_in.c
index 7b2090d..c5787fd 100644
--- a/arch/arm/mach-msm/qdsp5/audio_pcm_in.c
+++ b/arch/arm/mach-msm/qdsp5/audio_pcm_in.c
@@ -2,7 +2,7 @@
  *
  * pcm audio input device
  *
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This code is based in part on arch/arm/mach-msm/qdsp5v2/audio_pcm_in.c,
  * Copyright (C) 2008 Google, Inc.
@@ -42,6 +42,7 @@
 
 #include "audmgr.h"
 
+#include <mach/qdsp5/audio_acdb_def.h>
 #include <mach/qdsp5/qdsp5audpreproc.h>
 #include <mach/qdsp5/qdsp5audpreproccmdi.h>
 #include <mach/qdsp5/qdsp5audpreprocmsg.h>
@@ -346,6 +347,8 @@
 	case AUDREC_MSG_CMD_AREC_PARAM_CFG_DONE_MSG: {
 		MM_INFO("PARAM CFG DONE\n");
 		audio->running = 1;
+		if (is_acdb_enabled())
+			break;
 		audio_dsp_set_tx_agc(audio);
 		audio_dsp_set_ns(audio);
 		audio_dsp_set_iir(audio);
@@ -914,6 +917,12 @@
 	mutex_lock(&audio->lock);
 	switch (cmd) {
 	case AUDIO_ENABLE_AUDPRE:
+
+		if (is_acdb_enabled()) {
+			MM_INFO("Audpp is supported via acdb\n");
+			rc = -EFAULT;
+			break;
+		}
 		if (copy_from_user(&enable_mask, (void *) arg,
 						sizeof(enable_mask))) {
 			rc = -EFAULT;
diff --git a/arch/arm/mach-msm/smd_pkt.c b/arch/arm/mach-msm/smd_pkt.c
index 73ebdf6..8e7a1f5 100644
--- a/arch/arm/mach-msm/smd_pkt.c
+++ b/arch/arm/mach-msm/smd_pkt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
@@ -855,6 +855,12 @@
 				r = PTR_ERR(smd_pkt_devp->pil);
 				pr_err("%s failed on smd_pkt_dev id:%d - subsystem_get failed for %s\n",
 					__func__, smd_pkt_devp->i, peripheral);
+				/*
+				 * Sleep inorder to reduce the frequency of
+				 * retry by user-space modules and to avoid
+				 * possible watchdog bite.
+				 */
+				msleep((smd_pkt_devp->open_modem_wait * 1000));
 				goto release_pd;
 			}
 
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index 2743547..47d311c 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.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
@@ -15,9 +15,17 @@
  *
  */
 
-#include <linux/types.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/sys_soc.h>
+#include <linux/slab.h>
+#include <linux/stat.h>
 #include <linux/sysdev.h>
+#include <linux/types.h>
+
 #include <asm/mach-types.h>
+
 #include <mach/socinfo.h>
 
 #include "smd_private.h"
@@ -399,6 +407,11 @@
 		: 0;
 }
 
+static uint32_t socinfo_get_format(void)
+{
+	return socinfo ? socinfo->v1.format : 0;
+}
+
 enum msm_cpu socinfo_get_msm_cpu(void)
 {
 	return cur_cpu;
@@ -607,6 +620,100 @@
 		socinfo_get_pmic_die_revision());
 }
 
+static ssize_t
+msm_get_vendor(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "Qualcomm\n");
+}
+
+static ssize_t
+msm_get_raw_id(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+		socinfo_get_raw_id());
+}
+
+static ssize_t
+msm_get_raw_version(struct device *dev,
+		     struct device_attribute *attr,
+		     char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+		socinfo_get_raw_version());
+}
+
+static ssize_t
+msm_get_build_id(struct device *dev,
+		   struct device_attribute *attr,
+		   char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%-.32s\n",
+			socinfo_get_build_id());
+}
+
+static ssize_t
+msm_get_hw_platform(struct device *dev,
+			struct device_attribute *attr,
+			char *buf)
+{
+	uint32_t hw_type;
+	hw_type = socinfo_get_platform_type();
+
+	return snprintf(buf, PAGE_SIZE, "%-.32s\n",
+			hw_platform[hw_type]);
+}
+
+static ssize_t
+msm_get_platform_version(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+		socinfo_get_platform_version());
+}
+
+static ssize_t
+msm_get_accessory_chip(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+		socinfo_get_accessory_chip());
+}
+
+static ssize_t
+msm_get_platform_subtype(struct device *dev,
+			struct device_attribute *attr,
+			char *buf)
+{
+	uint32_t hw_subtype;
+	hw_subtype = socinfo_get_platform_subtype();
+	return snprintf(buf, PAGE_SIZE, "%-.32s\n",
+		hw_platform_subtype[hw_subtype]);
+}
+
+static ssize_t
+msm_get_pmic_model(struct device *dev,
+			struct device_attribute *attr,
+			char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+		socinfo_get_pmic_model());
+}
+
+static ssize_t
+msm_get_pmic_die_revision(struct device *dev,
+			       struct device_attribute *attr,
+			       char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+			 socinfo_get_pmic_die_revision());
+}
+
 static struct sysdev_attribute socinfo_v1_files[] = {
 	_SYSDEV_ATTR(id, 0444, socinfo_show_id, NULL),
 	_SYSDEV_ATTR(version, 0444, socinfo_show_version, NULL),
@@ -644,6 +751,42 @@
 			socinfo_show_pmic_die_revision, NULL),
 };
 
+static struct device_attribute msm_soc_attr_raw_version =
+	__ATTR(raw_version, S_IRUGO, msm_get_raw_version,  NULL);
+
+static struct device_attribute msm_soc_attr_raw_id =
+	__ATTR(raw_id, S_IRUGO, msm_get_raw_id,  NULL);
+
+static struct device_attribute msm_soc_attr_vendor =
+	__ATTR(vendor, S_IRUGO, msm_get_vendor,  NULL);
+
+static struct device_attribute msm_soc_attr_build_id =
+	__ATTR(build_id, S_IRUGO, msm_get_build_id, NULL);
+
+static struct device_attribute msm_soc_attr_hw_platform =
+	__ATTR(hw_platform, S_IRUGO, msm_get_hw_platform, NULL);
+
+
+static struct device_attribute msm_soc_attr_platform_version =
+	__ATTR(platform_version, S_IRUGO,
+			msm_get_platform_version, NULL);
+
+static struct device_attribute msm_soc_attr_accessory_chip =
+	__ATTR(accessory_chip, S_IRUGO,
+			msm_get_accessory_chip, NULL);
+
+static struct device_attribute msm_soc_attr_platform_subtype =
+	__ATTR(platform_subtype, S_IRUGO,
+			msm_get_platform_subtype, NULL);
+
+static struct device_attribute msm_soc_attr_pmic_model =
+	__ATTR(pmic_model, S_IRUGO,
+			msm_get_pmic_model, NULL);
+
+static struct device_attribute msm_soc_attr_pmic_die_revision =
+	__ATTR(pmic_die_revision, S_IRUGO,
+			msm_get_pmic_die_revision, NULL);
+
 static struct sysdev_class soc_sysdev_class = {
 	.name = "soc",
 };
@@ -764,47 +907,63 @@
 	return (void *) &dummy_socinfo;
 }
 
-int __init socinfo_init(void)
+static void __init populate_soc_sysfs_files(struct device *msm_soc_device)
 {
-	socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID, sizeof(struct socinfo_v7));
+	uint32_t legacy_format = socinfo_get_format();
 
-	if (!socinfo)
-		socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
-				sizeof(struct socinfo_v6));
+	device_create_file(msm_soc_device, &msm_soc_attr_vendor);
 
-	if (!socinfo)
-		socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
-				sizeof(struct socinfo_v5));
-
-	if (!socinfo)
-		socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
-				sizeof(struct socinfo_v4));
-
-	if (!socinfo)
-		socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
-				sizeof(struct socinfo_v3));
-
-	if (!socinfo)
-		socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
-				sizeof(struct socinfo_v2));
-
-	if (!socinfo)
-		socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
-				sizeof(struct socinfo_v1));
-
-	if (!socinfo) {
-		pr_warn("%s: Can't find SMEM_HW_SW_BUILD_ID; falling back on "
-			"dummy values.\n", __func__);
-		socinfo = setup_dummy_socinfo();
+	switch (legacy_format) {
+	case 7:
+		device_create_file(msm_soc_device,
+					&msm_soc_attr_pmic_model);
+		device_create_file(msm_soc_device,
+					&msm_soc_attr_pmic_die_revision);
+	case 6:
+		device_create_file(msm_soc_device,
+					&msm_soc_attr_platform_subtype);
+	case 5:
+		device_create_file(msm_soc_device,
+					&msm_soc_attr_accessory_chip);
+	case 4:
+		device_create_file(msm_soc_device,
+					&msm_soc_attr_platform_version);
+	case 3:
+		device_create_file(msm_soc_device,
+					&msm_soc_attr_hw_platform);
+	case 2:
+		device_create_file(msm_soc_device,
+					&msm_soc_attr_raw_id);
+		device_create_file(msm_soc_device,
+					&msm_soc_attr_raw_version);
+	case 1:
+		device_create_file(msm_soc_device,
+					&msm_soc_attr_build_id);
+		break;
+	default:
+		pr_err("%s:Unknown socinfo format:%u\n", __func__,
+				legacy_format);
+		break;
 	}
 
-	WARN(!socinfo_get_id(), "Unknown SOC ID!\n");
-	WARN(socinfo_get_id() >= ARRAY_SIZE(cpu_of_id),
-		"New IDs added! ID => CPU mapping might need an update.\n");
+	return;
+}
 
-	if (socinfo->v1.id < ARRAY_SIZE(cpu_of_id))
-		cur_cpu = cpu_of_id[socinfo->v1.id];
+static void  __init soc_info_populate(struct soc_device_attribute *soc_dev_attr)
+{
+	uint32_t soc_version = socinfo_get_version();
 
+	soc_dev_attr->soc_id   = kasprintf(GFP_KERNEL, "%d", socinfo_get_id());
+	soc_dev_attr->machine  = "Snapdragon";
+	soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%u.%u",
+			SOCINFO_VERSION_MAJOR(soc_version),
+			SOCINFO_VERSION_MINOR(soc_version));
+	return;
+
+}
+
+static void socinfo_print(void)
+{
 	switch (socinfo->v1.format) {
 	case 1:
 		pr_info("%s: v%u, id=%u, ver=%u.%u\n",
@@ -880,8 +1039,69 @@
 		pr_err("%s: Unknown format found\n", __func__);
 		break;
 	}
+}
 
-	return 0;
+struct device *  __init socinfo_init(void)
+{
+	struct device *msm_soc_device;
+	struct soc_device *soc_dev;
+	struct soc_device_attribute *soc_dev_attr;
+
+	socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID, sizeof(struct socinfo_v7));
+
+	if (!socinfo)
+		socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
+				sizeof(struct socinfo_v6));
+
+	if (!socinfo)
+		socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
+				sizeof(struct socinfo_v5));
+
+	if (!socinfo)
+		socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
+				sizeof(struct socinfo_v4));
+
+	if (!socinfo)
+		socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
+				sizeof(struct socinfo_v3));
+
+	if (!socinfo)
+		socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
+				sizeof(struct socinfo_v2));
+
+	if (!socinfo)
+		socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID,
+				sizeof(struct socinfo_v1));
+
+	if (!socinfo) {
+		pr_warn("%s: Can't find SMEM_HW_SW_BUILD_ID; falling back on dummy values.\n",
+				__func__);
+		socinfo = setup_dummy_socinfo();
+	}
+
+	WARN(!socinfo_get_id(), "Unknown SOC ID!\n");
+	WARN(socinfo_get_id() >= ARRAY_SIZE(cpu_of_id),
+		"New IDs added! ID => CPU mapping might need an update.\n");
+
+	if (socinfo->v1.id < ARRAY_SIZE(cpu_of_id))
+		cur_cpu = cpu_of_id[socinfo->v1.id];
+
+	socinfo_print();
+	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+	if (!soc_dev_attr)
+		return ERR_PTR(-ENOMEM);
+
+	soc_info_populate(soc_dev_attr);
+	soc_dev = soc_device_register(soc_dev_attr);
+	if (IS_ERR_OR_NULL(soc_dev)) {
+		kfree(soc_dev_attr);
+		return ERR_PTR(-EIO);
+	}
+
+	msm_soc_device = soc_device_to_device(soc_dev);
+	populate_soc_sysfs_files(msm_soc_device);
+
+	return msm_soc_device;
 }
 
 const int get_core_count(void)
diff --git a/arch/arm/mach-msm/test_qmi_client.c b/arch/arm/mach-msm/test_qmi_client.c
new file mode 100644
index 0000000..d070e37
--- /dev/null
+++ b/arch/arm/mach-msm/test_qmi_client.c
@@ -0,0 +1,344 @@
+/* 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 <linux/module.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/debugfs.h>
+#include <linux/qmi_encdec.h>
+
+#include <asm/uaccess.h>
+
+#include <mach/msm_qmi_interface.h>
+
+#include "kernel_test_service_v01.h"
+
+#define TEST_SERVICE_SVC_ID 0x0000000f
+#define TEST_SERVICE_INS_ID 1
+
+static int test_rep_cnt = 10;
+module_param_named(rep_cnt, test_rep_cnt, int, S_IRUGO | S_IWUSR | S_IWGRP);
+
+static int test_data_sz = 50;
+module_param_named(data_sz, test_data_sz, int, S_IRUGO | S_IWUSR | S_IWGRP);
+
+static int test_clnt_debug_mask;
+module_param_named(debug_mask, test_clnt_debug_mask,
+		   int, S_IRUGO | S_IWUSR | S_IWGRP);
+
+#define D(x...) do { \
+	if (test_clnt_debug_mask) \
+		pr_debug(x); \
+} while (0)
+
+/* Variable to initiate the test through debugfs interface */
+static struct dentry *test_dent;
+
+/* Test client port for IPC Router */
+static struct qmi_handle *test_clnt;
+static int test_clnt_reset;
+
+/* Reader thread to receive responses & indications */
+static void test_clnt_recv_msg(struct work_struct *work);
+static DECLARE_DELAYED_WORK(work_recv_msg, test_clnt_recv_msg);
+static void test_clnt_svc_arrive(struct work_struct *work);
+static DECLARE_DELAYED_WORK(work_svc_arrive, test_clnt_svc_arrive);
+static void test_clnt_svc_exit(struct work_struct *work);
+static DECLARE_DELAYED_WORK(work_svc_exit, test_clnt_svc_exit);
+static struct workqueue_struct *test_clnt_workqueue;
+
+/* Variable to hold the test result */
+static int test_res;
+
+static int test_qmi_ping_pong_send_sync_msg(void)
+{
+	struct test_ping_req_msg_v01 req;
+	struct test_ping_resp_msg_v01 resp;
+	struct msg_desc req_desc, resp_desc;
+	int rc;
+
+	memcpy(req.ping, "ping", sizeof(req.ping));
+	req.client_name_valid = 0;
+
+	req_desc.max_msg_len = TEST_PING_REQ_MAX_MSG_LEN_V01;
+	req_desc.msg_id = TEST_PING_REQ_MSG_ID_V01;
+	req_desc.ei_array = test_ping_req_msg_v01_ei;
+
+	resp_desc.max_msg_len = TEST_PING_REQ_MAX_MSG_LEN_V01;
+	resp_desc.msg_id = TEST_PING_REQ_MSG_ID_V01;
+	resp_desc.ei_array = test_ping_resp_msg_v01_ei;
+
+	rc = qmi_send_req_wait(test_clnt, &req_desc, &req, sizeof(req),
+			       &resp_desc, &resp, sizeof(resp), 0);
+	if (rc < 0) {
+		pr_err("%s: send req failed %d\n", __func__, rc);
+		return rc;
+	}
+
+	D("%s: Received %s response\n", __func__, resp.pong);
+	return rc;
+}
+
+static int test_qmi_data_send_sync_msg(unsigned int data_len)
+{
+	struct test_data_req_msg_v01 *req;
+	struct test_data_resp_msg_v01 *resp;
+	struct msg_desc req_desc, resp_desc;
+	int rc, i;
+
+	req = kzalloc(sizeof(struct test_data_req_msg_v01), GFP_KERNEL);
+	if (!req) {
+		pr_err("%s: Data req msg alloc failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	resp = kzalloc(sizeof(struct test_data_resp_msg_v01), GFP_KERNEL);
+	if (!resp) {
+		pr_err("%s: Data resp msg alloc failed\n", __func__);
+		kfree(req);
+		return -ENOMEM;
+	}
+
+	req->data_len = data_len;
+	for (i = 0; i < data_len; i = i + sizeof(int))
+		memcpy(req->data + i, (uint8_t *)&i, sizeof(int));
+	req->client_name_valid = 0;
+
+	req_desc.max_msg_len = TEST_DATA_REQ_MAX_MSG_LEN_V01;
+	req_desc.msg_id = TEST_DATA_REQ_MSG_ID_V01;
+	req_desc.ei_array = test_data_req_msg_v01_ei;
+
+	resp_desc.max_msg_len = TEST_DATA_REQ_MAX_MSG_LEN_V01;
+	resp_desc.msg_id = TEST_DATA_REQ_MSG_ID_V01;
+	resp_desc.ei_array = test_data_resp_msg_v01_ei;
+
+	rc = qmi_send_req_wait(test_clnt, &req_desc, req, sizeof(*req),
+			       &resp_desc, resp, sizeof(*resp), 0);
+	if (rc < 0) {
+		pr_err("%s: send req failed\n", __func__);
+		goto data_send_err;
+	}
+
+	D("%s: data_valid %d\n", __func__, resp->data_valid);
+	D("%s: data_len %d\n", __func__, resp->data_len);
+data_send_err:
+	kfree(resp);
+	kfree(req);
+	return rc;
+}
+
+static void test_clnt_recv_msg(struct work_struct *work)
+{
+	int rc;
+
+	rc = qmi_recv_msg(test_clnt);
+	if (rc < 0)
+		pr_err("%s: Error receiving message\n", __func__);
+}
+
+static void test_clnt_notify(struct qmi_handle *handle,
+			     enum qmi_event_type event, void *notify_priv)
+{
+	switch (event) {
+	case QMI_RECV_MSG:
+		queue_delayed_work(test_clnt_workqueue,
+				   &work_recv_msg, 0);
+		break;
+	default:
+		break;
+	}
+}
+
+static void test_clnt_svc_arrive(struct work_struct *work)
+{
+	int rc;
+
+	D("%s begins\n", __func__);
+
+	/* Create a Local client port for QMI communication */
+	test_clnt = qmi_handle_create(test_clnt_notify, NULL);
+	if (!test_clnt) {
+		pr_err("%s: QMI client handle alloc failed\n", __func__);
+		return;
+	}
+
+	D("%s: Lookup server name\n", __func__);
+	rc = qmi_connect_to_service(test_clnt, TEST_SERVICE_SVC_ID,
+				    TEST_SERVICE_INS_ID);
+	if (rc < 0) {
+		pr_err("%s: Server not found\n", __func__);
+		qmi_handle_destroy(test_clnt);
+		test_clnt = NULL;
+		return;
+	}
+	test_clnt_reset = 0;
+	D("%s complete\n", __func__);
+}
+
+static void test_clnt_svc_exit(struct work_struct *work)
+{
+	D("%s begins\n", __func__);
+
+	qmi_handle_destroy(test_clnt);
+	test_clnt_reset = 1;
+	test_clnt = NULL;
+
+	D("%s complete\n", __func__);
+}
+
+static int test_clnt_svc_event_notify(struct notifier_block *this,
+				      unsigned long code,
+				      void *_cmd)
+{
+	D("%s: event %ld\n", __func__, code);
+	switch (code) {
+	case QMI_SERVER_ARRIVE:
+		queue_delayed_work(test_clnt_workqueue,
+				   &work_svc_arrive, 0);
+		break;
+	case QMI_SERVER_EXIT:
+		queue_delayed_work(test_clnt_workqueue,
+				   &work_svc_exit, 0);
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static int test_qmi_open(struct inode *ip, struct file *fp)
+{
+	if (!test_clnt) {
+		pr_err("%s Test client is not initialized\n", __func__);
+		return -ENODEV;
+	}
+	return 0;
+}
+
+static ssize_t test_qmi_read(struct file *fp, char __user *buf,
+		size_t count, loff_t *pos)
+{
+	char _buf[16];
+	snprintf(_buf, sizeof(_buf), "%d\n", test_res);
+	test_res = 0;
+	return simple_read_from_buffer(buf, count, pos,
+				       _buf, strnlen(_buf, 16));
+}
+
+static int test_qmi_release(struct inode *ip, struct file *fp)
+{
+	return 0;
+}
+
+static ssize_t test_qmi_write(struct file *fp, const char __user *buf,
+			size_t count, loff_t *pos)
+{
+	unsigned char cmd[64];
+	int len;
+	int i;
+
+	if (count < 1)
+		return 0;
+
+	len = min(count, (sizeof(cmd) - 1));
+
+	if (copy_from_user(cmd, buf, len))
+		return -EFAULT;
+
+	cmd[len] = 0;
+	if (cmd[len-1] == '\n') {
+		cmd[len-1] = 0;
+		len--;
+	}
+
+	if (!strncmp(cmd, "ping_pong", sizeof(cmd))) {
+		for (i = 0; i < test_rep_cnt; i++) {
+			test_res = test_qmi_ping_pong_send_sync_msg();
+			if (test_res == -ENETRESET || test_clnt_reset) {
+				do {
+					msleep(50);
+				} while (test_clnt_reset);
+			}
+		}
+	} else if (!strncmp(cmd, "data", sizeof(cmd))) {
+		for (i = 0; i < test_rep_cnt; i++) {
+			test_res = test_qmi_data_send_sync_msg(test_data_sz);
+			if (test_res == -ENETRESET || test_clnt_reset) {
+				do {
+					msleep(50);
+				} while (test_clnt_reset);
+			}
+		}
+	} else {
+		test_res = -EINVAL;
+	}
+	return count;
+}
+
+static struct notifier_block test_clnt_nb = {
+	.notifier_call = test_clnt_svc_event_notify,
+};
+
+static const struct file_operations debug_ops = {
+	.owner = THIS_MODULE,
+	.open = test_qmi_open,
+	.read = test_qmi_read,
+	.write = test_qmi_write,
+	.release = test_qmi_release,
+};
+
+static int __init test_qmi_init(void)
+{
+	int rc;
+
+	test_clnt_workqueue = create_singlethread_workqueue("test_clnt");
+	if (!test_clnt_workqueue)
+		return -EFAULT;
+
+	rc = qmi_svc_event_notifier_register(TEST_SERVICE_SVC_ID,
+				TEST_SERVICE_INS_ID, &test_clnt_nb);
+	if (rc < 0) {
+		pr_err("%s: notifier register failed\n", __func__);
+		destroy_workqueue(test_clnt_workqueue);
+		return rc;
+	}
+
+	test_dent = debugfs_create_file("test_qmi_client", 0444, 0,
+					 NULL, &debug_ops);
+	if (IS_ERR(test_dent)) {
+		pr_err("%s: unable to create debugfs %ld\n",
+			__func__, IS_ERR(test_dent));
+		test_dent = NULL;
+		qmi_svc_event_notifier_unregister(TEST_SERVICE_SVC_ID,
+					TEST_SERVICE_INS_ID, &test_clnt_nb);
+		destroy_workqueue(test_clnt_workqueue);
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+static void __exit test_qmi_exit(void)
+{
+	qmi_svc_event_notifier_unregister(TEST_SERVICE_SVC_ID,
+					TEST_SERVICE_INS_ID, &test_clnt_nb);
+	destroy_workqueue(test_clnt_workqueue);
+	debugfs_remove(test_dent);
+}
+
+module_init(test_qmi_init);
+module_exit(test_qmi_exit);
+
+MODULE_DESCRIPTION("TEST QMI Client Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index 0b395c5..79f20a4 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -321,4 +321,8 @@
 
 extern struct diag_bridge_dev *diag_bridge;
 extern struct diagchar_dev *driver;
+
+extern int wrap_enabled;
+extern uint16_t wrap_count;
+
 #endif
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 6a7f55f..f6c26c3 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -84,11 +84,23 @@
 static int token_list[MAX_PROC] = {0, -1, -2, -3, -4, -5, -6, -7, -8, -9};
 
 #define DIAGPKT_MAX_DELAYED_RSP 0xFFFF
-/* This macro gets the next delayed respose id. Once it reaches
- DIAGPKT_MAX_DELAYED_RSP, it stays at DIAGPKT_MAX_DELAYED_RSP */
 
-#define DIAGPKT_NEXT_DELAYED_RSP_ID(x) 				\
-((x < DIAGPKT_MAX_DELAYED_RSP) ? x++ : DIAGPKT_MAX_DELAYED_RSP)
+/* returns the next delayed rsp id - rollsover the id if wrapping is
+   enabled. */
+uint16_t diagpkt_next_delayed_rsp_id(uint16_t rspid)
+{
+	if (rspid < DIAGPKT_MAX_DELAYED_RSP)
+		rspid++;
+	else {
+		if (wrap_enabled) {
+			rspid = 1;
+			wrap_count++;
+		} else
+			rspid = DIAGPKT_MAX_DELAYED_RSP;
+	}
+	delayed_rsp_id = rspid;
+	return delayed_rsp_id;
+}
 
 #define COPY_USER_SPACE_OR_EXIT(buf, data, length)		\
 do {								\
@@ -534,7 +546,7 @@
 		if ((delay_params.rsp_ptr) &&
 		 (delay_params.size == sizeof(delayed_rsp_id)) &&
 				 (delay_params.num_bytes_ptr)) {
-			interim_rsp_id = DIAGPKT_NEXT_DELAYED_RSP_ID(
+			interim_rsp_id = diagpkt_next_delayed_rsp_id(
 							delayed_rsp_id);
 			if (copy_to_user((void *)delay_params.rsp_ptr,
 					 &interim_rsp_id, sizeof(uint16_t)))
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 6b4c337..0bd26cf 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -51,6 +51,8 @@
 struct diag_master_table entry;
 struct diag_send_desc_type send = { NULL, NULL, DIAG_STATE_START, 0 };
 struct diag_hdlc_dest_type enc = { NULL, NULL, 0 };
+int wrap_enabled;
+uint16_t wrap_count;
 
 void encode_rsp_and_send(int buf_length)
 {
@@ -896,6 +898,23 @@
 			return 0;
 		}
 	}
+	/* Return the Delayed Response Wrap Status */
+	else if ((*buf == 0x4b) && (*(buf+1) == 0x32) &&
+		(*(buf+2) == 0x04) && (*(buf+3) == 0x0)) {
+		memcpy(driver->apps_rsp_buf, buf, 4);
+		driver->apps_rsp_buf[4] = wrap_enabled;
+		encode_rsp_and_send(4);
+		return 0;
+	}
+	/* Wrap the Delayed Rsp ID */
+	else if ((*buf == 0x4b) && (*(buf+1) == 0x32) &&
+		(*(buf+2) == 0x05) && (*(buf+3) == 0x0)) {
+		wrap_enabled = true;
+		memcpy(driver->apps_rsp_buf, buf, 4);
+		driver->apps_rsp_buf[4] = wrap_count;
+		encode_rsp_and_send(5);
+		return 0;
+	}
 	 /* Check for ID for NO MODEM present */
 	else if (chk_polling_response()) {
 		/* respond to 0x0 command */
@@ -1449,6 +1468,8 @@
 	int success;
 	int i;
 
+	wrap_enabled = 0;
+	wrap_count = 0;
 	diag_debug_buf_idx = 0;
 	driver->read_len_legacy = 0;
 	driver->use_device_tree = has_device_tree();
diff --git a/drivers/hwmon/pm8xxx-adc-scale.c b/drivers/hwmon/pm8xxx-adc-scale.c
index 4a1f58c..56c352a 100644
--- a/drivers/hwmon/pm8xxx-adc-scale.c
+++ b/drivers/hwmon/pm8xxx-adc-scale.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
@@ -271,172 +271,174 @@
 };
 
 static const struct pm8xxx_adc_map_pt adcmap_ntcg_104ef_104fb[] = {
-	{696483,	-40960},
-	{649148,	-39936},
-	{605368,	-38912},
-	{564809,	-37888},
-	{527215,	-36864},
-	{492322,	-35840},
-	{460007,	-34816},
-	{429982,	-33792},
-	{402099,	-32768},
-	{376192,	-31744},
-	{352075,	-30720},
-	{329714,	-29696},
-	{308876,	-28672},
-	{289480,	-27648},
-	{271417,	-26624},
-	{254574,	-25600},
-	{238903,	-24576},
-	{224276,	-23552},
-	{210631,	-22528},
-	{197896,	-21504},
-	{186007,	-20480},
-	{174899,	-19456},
-	{164521,	-18432},
-	{154818,	-17408},
-	{145744,	-16384},
-	{137265,	-15360},
-	{129307,	-14336},
-	{121866,	-13312},
-	{114896,	-12288},
-	{108365,	-11264},
-	{102252,	-10240},
-	{96499,		-9216},
-	{91111,		-8192},
-	{86055,		-7168},
-	{81308,		-6144},
-	{76857,		-5120},
-	{72660,		-4096},
-	{68722,		-3072},
-	{65020,		-2048},
-	{61538,		-1024},
-	{58261,		0},
-	{55177,		1024},
-	{52274,		2048},
-	{49538,		3072},
-	{46962,		4096},
-	{44531,		5120},
-	{42243,		6144},
-	{40083,		7168},
-	{38045,		8192},
-	{36122,		9216},
-	{34308,		10240},
-	{32592,		11264},
-	{30972,		12288},
-	{29442,		13312},
-	{27995,		14336},
-	{26624,		15360},
-	{25333,		16384},
-	{24109,		17408},
-	{22951,		18432},
-	{21854,		19456},
-	{20807,		20480},
-	{19831,		21504},
-	{18899,		22528},
-	{18016,		23552},
-	{17178,		24576},
-	{16384,		25600},
-	{15631,		26624},
-	{14916,		27648},
-	{14237,		28672},
-	{13593,		29696},
-	{12976,		30720},
-	{12400,		31744},
-	{11848,		32768},
-	{11324,		33792},
-	{10825,		34816},
-	{10354,		35840},
-	{9900,		36864},
-	{9471,		37888},
-	{9062,		38912},
-	{8674,		39936},
-	{8306,		40960},
-	{7951,		41984},
-	{7616,		43008},
-	{7296,		44032},
-	{6991,		45056},
-	{6701,		46080},
-	{6424,		47104},
-	{6160,		48128},
-	{5908,		49152},
-	{5667,		50176},
-	{5439,		51200},
-	{5219,		52224},
-	{5010,		53248},
-	{4810,		54272},
-	{4619,		55296},
-	{4440,		56320},
-	{4263,		57344},
-	{4097,		58368},
-	{3938,		59392},
-	{3785,		60416},
-	{3637,		61440},
-	{3501,		62464},
-	{3368,		63488},
-	{3240,		64512},
-	{3118,		65536},
-	{2998,		66560},
-	{2889,		67584},
-	{2782,		68608},
-	{2680,		69632},
-	{2581,		70656},
-	{2490,		71680},
-	{2397,		72704},
-	{2310,		73728},
-	{2227,		74752},
-	{2147,		75776},
-	{2064,		76800},
-	{1998,		77824},
-	{1927,		78848},
-	{1860,		79872},
-	{1795,		80896},
-	{1736,		81920},
-	{1673,		82944},
-	{1615,		83968},
-	{1560,		84992},
-	{1507,		86016},
-	{1456,		87040},
-	{1407,		88064},
-	{1360,		89088},
-	{1314,		90112},
-	{1271,		91136},
-	{1228,		92160},
-	{1189,		93184},
-	{1150,		94208},
-	{1112,		95232},
-	{1076,		96256},
-	{1042,		97280},
-	{1008,		98304},
-	{976,		99328},
-	{945,		100352},
-	{915,		101376},
+	{374682,	-40960},
+	{360553,	-39936},
+	{346630,	-38912},
+	{332940,	-37888},
+	{319510,	-36864},
+	{306363,	-35840},
+	{293521,	-34816},
+	{281001,	-33792},
+	{268818,	-32768},
+	{256987,	-31744},
+	{245516,	-30720},
+	{234413,	-29696},
+	{223685,	-28672},
+	{213333,	-27648},
+	{203360,	-26624},
+	{193763,	-25600},
+	{184541,	-24576},
+	{175691,	-23552},
+	{167205,	-22528},
+	{159079,	-21504},
+	{151304,	-20480},
+	{143872,	-19456},
+	{136775,	-18432},
+	{130001,	-17408},
+	{123542,	-16384},
+	{117387,	-15360},
+	{111526,	-14336},
+	{105946,	-13312},
+	{100639,	-12288},
+	{95592,		-11264},
+	{90795,		-10240},
+	{86238,		-9216},
+	{81909,		-8192},
+	{77800,		-7168},
+	{73899,		-6144},
+	{70197,		-5120},
+	{66685,		-4096},
+	{63354,		-3072},
+	{60194,		-2048},
+	{57198,		-1024},
+	{54356,		0},
+	{51662,		1024},
+	{49108,		2048},
+	{46687,		3072},
+	{44391,		4096},
+	{42215,		5120},
+	{40151,		6144},
+	{38195,		7168},
+	{36340,		8192},
+	{34582,		9216},
+	{32914,		10240},
+	{31333,		11264},
+	{29833,		12288},
+	{28410,		13312},
+	{27061,		14336},
+	{25781,		15360},
+	{24566,		16384},
+	{23413,		17408},
+	{22319,		18432},
+	{21280,		19456},
+	{20294,		20480},
+	{19358,		21504},
+	{18469,		22528},
+	{17624,		23552},
+	{16822,		24576},
+	{16060,		25600},
+	{15335,		26624},
+	{14646,		27648},
+	{13992,		28672},
+	{13369,		29696},
+	{12777,		30720},
+	{12214,		31744},
+	{11678,		32768},
+	{11168,		33792},
+	{10682,		34816},
+	{10220,		35840},
+	{9780,		36864},
+	{9361,		37888},
+	{8962,		38912},
+	{8582,		39936},
+	{8219,		40960},
+	{7874,		41984},
+	{7545,		43008},
+	{7231,		44032},
+	{6931,		45056},
+	{6646,		46080},
+	{6373,		47104},
+	{6113,		48128},
+	{5865,		49152},
+	{5628,		50176},
+	{5402,		51200},
+	{5185,		52224},
+	{4979,		53248},
+	{4782,		54272},
+	{4593,		55296},
+	{4413,		56320},
+	{4241,		57344},
+	{4076,		58368},
+	{3919,		59392},
+	{3768,		60416},
+	{3624,		61440},
+	{3486,		62464},
+	{3354,		63488},
+	{3227,		64512},
+	{3106,		65536},
+	{2990,		66560},
+	{2879,		67584},
+	{2773,		68608},
+	{2671,		69632},
+	{2573,		70656},
+	{2479,		71680},
+	{2390,		72704},
+	{2303,		73728},
+	{2221,		74752},
+	{2142,		75776},
+	{2066,		76800},
+	{1993,		77824},
+	{1923,		78848},
+	{1855,		79872},
+	{1791,		80896},
+	{1729,		81920},
+	{1669,		82944},
+	{1612,		83968},
+	{1557,		84992},
+	{1504,		86016},
+	{1453,		87040},
+	{1404,		88064},
+	{1357,		89088},
+	{1312,		90112},
+	{1269,		91136},
+	{1227,		92160},
+	{1187,		93184},
+	{1148,		94208},
+	{1111,		95232},
+	{1075,		96256},
+	{1040,		97280},
+	{1007,		98304},
+	{975,		99328},
+	{944,		100352},
+	{914,		101376},
 	{886,		102400},
-	{859,		103424},
-	{832,		104448},
-	{807,		105472},
-	{782,		106496},
-	{756,		107520},
-	{735,		108544},
+	{858,		103424},
+	{831,		104448},
+	{806,		105472},
+	{781,		106496},
+	{757,		107520},
+	{734,		108544},
 	{712,		109568},
-	{691,		110592},
+	{690,		110592},
 	{670,		111616},
 	{650,		112640},
-	{631,		113664},
+	{630,		113664},
 	{612,		114688},
 	{594,		115712},
-	{577,		116736},
-	{560,		117760},
-	{544,		118784},
-	{528,		119808},
-	{513,		120832},
+	{576,		116736},
+	{559,		117760},
+	{543,		118784},
+	{527,		119808},
+	{512,		120832},
 	{498,		121856},
 	{483,		122880},
 	{470,		123904},
-	{457,		124928},
+	{456,		124928},
 	{444,		125952},
 	{431,		126976},
-	{419,		128000}
+	{419,		128000},
+	{408,		129024},
+	{396,		130048}
 };
 
 static int32_t pm8xxx_adc_map_linear(const struct pm8xxx_adc_map_pt *pts,
@@ -716,6 +718,10 @@
 		struct pm8xxx_adc_chan_result *adc_chan_result)
 {
 	int64_t xo_thm = 0;
+	uint32_t num1 = 0;
+	uint32_t num2 = 0;
+	uint32_t dnum = 0;
+	uint32_t rt_r25 = 0;
 
 	if (!chan_properties || !chan_properties->offset_gain_numerator ||
 		!chan_properties->offset_gain_denominator || !adc_properties
@@ -724,10 +730,21 @@
 
 	xo_thm = pm8xxx_adc_scale_ratiometric_calib(adc_code,
 			adc_properties, chan_properties);
-	xo_thm <<= 4;
+	if (xo_thm < 0)
+		xo_thm = -xo_thm;
+
+	num1 = xo_thm << 14;
+	num2 = (adc_properties->adc_vdd_reference - xo_thm) >> 1;
+	dnum = (adc_properties->adc_vdd_reference - xo_thm);
+
+	if (dnum == 0)
+		rt_r25 = 0x7FFFFFFF ;
+	else
+		rt_r25 = (num1 + num2)/dnum ;
+
 	pm8xxx_adc_map_linear(adcmap_ntcg_104ef_104fb,
 		ARRAY_SIZE(adcmap_ntcg_104ef_104fb),
-		xo_thm, &adc_chan_result->physical);
+		rt_r25, &adc_chan_result->physical);
 
 	return 0;
 }
diff --git a/drivers/hwmon/pm8xxx-adc.c b/drivers/hwmon/pm8xxx-adc.c
index 181a97e..1a163a4 100644
--- a/drivers/hwmon/pm8xxx-adc.c
+++ b/drivers/hwmon/pm8xxx-adc.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
@@ -1075,7 +1075,7 @@
 
 	return 0;
 }
-DEFINE_SIMPLE_ATTRIBUTE(reg_fops, get_adc, NULL, "%llu\n");
+DEFINE_SIMPLE_ATTRIBUTE(reg_fops, get_adc, NULL, "%lld\n");
 
 #ifdef CONFIG_DEBUG_FS
 static void create_debugfs_entries(void)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index bb505d8..2e807ac 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -233,14 +233,26 @@
 #define MXT_BOOT_VALUE		0xa5
 #define MXT_BACKUP_VALUE	0x55
 #define MXT_BACKUP_TIME		25	/* msec */
-#define MXT224_RESET_TIME	65	/* msec */
-#define MXT224E_RESET_TIME	150	/* msec */
-#define MXT1386_RESET_TIME	250	/* msec */
+
+/* Software reset delay */
+#define MXT224_RESET_TIME	64	/* msec */
+#define MXT224E_RESET_TIME	21	/* msec */
 #define MXT336S_RESET_TIME	25	/* msec */
-#define MXT1664S_RESET_TIME	65	/* msec */
+#define MXT1386_RESET_TIME	250	/* msec */
+#define MXT1386E_RESET_TIME	229	/* msec */
+#define MXT1664S_RESET_TIME	280	/* msec */
 #define MXT_RESET_TIME		250	/* msec */
 #define MXT_RESET_NOCHGREAD	400	/* msec */
 
+/* Power on delay */
+#define MXT224_POWER_ON_TIME	40	/* msec */
+#define MXT224E_POWER_ON_TIME	21	/* msec */
+#define MXT336S_POWER_ON_TIME	25	/* msec */
+#define MXT1386_POWER_ON_TIME	90	/* msec */
+#define MXT1386E_POWER_ON_TIME	81	/* msec */
+#define MXT1664S_POWER_ON_TIME	65	/* msec */
+#define MXT_POWER_ON_TIME	100	/* msec */
+
 #define MXT_FWRESET_TIME	1000	/* msec */
 
 #define MXT_WAKE_TIME		25
@@ -1291,6 +1303,42 @@
 	return 0;
 }
 
+static void mxt_power_on_delay(struct mxt_data *data)
+{
+	const struct mxt_platform_data *pdata = data->pdata;
+	const struct mxt_config_info *cfg_info;
+	u32 delay = 0;
+	int i;
+
+	for (i = 0; i < pdata->config_array_size; i++) {
+		cfg_info = &pdata->config_array[i];
+
+		switch (cfg_info->family_id) {
+		case MXT224_ID:
+			delay = max_t(u32, delay, MXT224_POWER_ON_TIME);
+			break;
+		case MXT224E_ID:
+			delay = max_t(u32, delay, MXT224E_POWER_ON_TIME);
+			break;
+		case MXT336S_ID:
+			delay = max_t(u32, delay, MXT336S_POWER_ON_TIME);
+			break;
+		case MXT1386_ID:
+			delay = max_t(u32, delay,
+					max_t(u32, MXT1386_POWER_ON_TIME,
+						MXT1386E_POWER_ON_TIME));
+			break;
+		case MXT1664S_ID:
+			delay = max_t(u32, delay, MXT1664S_POWER_ON_TIME);
+			break;
+		default:
+			delay = max_t(u32, delay, MXT_POWER_ON_TIME);
+		}
+	}
+
+	msleep(delay);
+}
+
 static void mxt_reset_delay(struct mxt_data *data)
 {
 	struct mxt_info *info = &data->info;
@@ -1304,8 +1352,10 @@
 		break;
 	case MXT336S_ID:
 		msleep(MXT336S_RESET_TIME);
+		break;
 	case MXT1386_ID:
-		msleep(MXT1386_RESET_TIME);
+		msleep(max_t(u32, MXT1386_RESET_TIME, MXT1386E_RESET_TIME));
+		break;
 	case MXT1664S_ID:
 		msleep(MXT1664S_RESET_TIME);
 		break;
@@ -2715,10 +2765,12 @@
 		}
 	}
 
-	mxt_reset_delay(data);
+	mxt_power_on_delay(data);
+
 	error = mxt_initialize(data);
 	if (error)
 		goto err_reset_gpio_req;
+
 	error = request_threaded_irq(client->irq, NULL, mxt_interrupt,
 			pdata->irqflags, client->dev.driver->name, data);
 	if (error) {
diff --git a/drivers/input/touchscreen/cyttsp-i2c-qc.c b/drivers/input/touchscreen/cyttsp-i2c-qc.c
index 6eba5d1..6c4e6b7 100644
--- a/drivers/input/touchscreen/cyttsp-i2c-qc.c
+++ b/drivers/input/touchscreen/cyttsp-i2c-qc.c
@@ -2881,17 +2881,17 @@
 
 	cyttsp_debug("Wake Up\n");
 
-	if (ts->is_suspended == false) {
-		pr_err("%s: in wakeup state\n", __func__);
-		return 0;
-	}
-
 	if (device_may_wakeup(dev)) {
 		if (ts->client->irq)
 			disable_irq_wake(ts->client->irq);
 		return 0;
 	}
 
+	if (ts->is_suspended == false) {
+		pr_err("%s: in wakeup state\n", __func__);
+		return 0;
+	}
+
 	/* re-enable the interrupt prior to wake device */
 	if (ts->client->irq)
 		enable_irq(ts->client->irq);
@@ -2952,6 +2952,12 @@
 
 	cyttsp_debug("Enter Sleep\n");
 
+	if (device_may_wakeup(dev)) {
+		if (ts->client->irq)
+			enable_irq_wake(ts->client->irq);
+		return 0;
+	}
+
 	if (ts->is_suspended == true) {
 		pr_err("%s: in sleep state\n", __func__);
 		return 0;
@@ -2966,11 +2972,6 @@
 	}
 	mutex_unlock(&ts->mutex);
 
-	if (device_may_wakeup(dev)) {
-		if (ts->client->irq)
-			enable_irq_wake(ts->client->irq);
-		return 0;
-	}
 
 	if (ts->client->irq == 0)
 		del_timer(&ts->timer);
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 86703e0..6fb11e1 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -16,7 +16,7 @@
 # MSM IOMMU support
 config MSM_IOMMU
 	bool "MSM IOMMU Support"
-	depends on ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_APQ8064 || ARCH_MSM8974 || ARCH_MPQ8092 || ARCH_MSM8910
+	depends on ARCH_MSM8X60 || ARCH_MSM8960 || ARCH_APQ8064 || ARCH_MSM8974 || ARCH_MPQ8092 || ARCH_MSM8910 || ARCH_MSM8226
 	select IOMMU_API
 	help
 	  Support for the IOMMUs found on certain Qualcomm SOCs.
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index 9b66b05..82b6aa0 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -4,7 +4,7 @@
  * Copyright (C) 2000 Ralph Metzler & Marcus Metzler
  *		      for convergence integrated media GmbH
  *
- * 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 Lesser General Public License
@@ -2255,6 +2255,7 @@
 
 	spin_lock_irq(&dmxdevfilter->dev->lock);
 	dvb_dmxdev_flush_output(&dmxdevfilter->buffer, &dmxdevfilter->events);
+	dvb_ringbuffer_reset(&dmxdevfilter->buffer);
 	spin_unlock_irq(&dmxdevfilter->dev->lock);
 
 	wake_up_all(&dmxdevfilter->buffer.queue);
diff --git a/drivers/media/video/vcap_vc.c b/drivers/media/video/vcap_vc.c
index 642074f..5760fba 100644
--- a/drivers/media/video/vcap_vc.c
+++ b/drivers/media/video/vcap_vc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, Code Aurora Forum. 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
@@ -132,23 +132,25 @@
 inline void vc_isr_error_checking(struct vcap_dev *dev,
 		struct v4l2_event v4l2_evt, uint32_t irq)
 {
-	if (irq & 0x8000200) {
-		writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
-		v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
-			VCAP_VC_PIX_ERR_EVENT;
-		v4l2_event_queue(dev->vfd, &v4l2_evt);
-	}
-	if (irq & 0x40000200) {
-		writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
-		v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
-			VCAP_VC_LINE_ERR_EVENT;
-		v4l2_event_queue(dev->vfd, &v4l2_evt);
-	}
-	if (irq & 0x20000200) {
-		writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
-		v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
-			VCAP_VC_VSYNC_ERR_EVENT;
-		v4l2_event_queue(dev->vfd, &v4l2_evt);
+	if (irq & 0x200) {
+		if (irq & 0x80000000) {
+			writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
+			v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
+				VCAP_VC_PIX_ERR_EVENT;
+			v4l2_event_queue(dev->vfd, &v4l2_evt);
+		}
+		if (irq & 0x40000000) {
+			writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
+			v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
+				VCAP_VC_LINE_ERR_EVENT;
+			v4l2_event_queue(dev->vfd, &v4l2_evt);
+		}
+		if (irq & 0x20000000) {
+			writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
+			v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
+				VCAP_VC_VSYNC_ERR_EVENT;
+			v4l2_event_queue(dev->vfd, &v4l2_evt);
+		}
 	}
 	if (irq & 0x00001000) {
 		writel_iowmb(0x00000102, VCAP_VC_NPL_CTRL);
diff --git a/drivers/misc/tspp.c b/drivers/misc/tspp.c
index d4ff38b..563a013 100644
--- a/drivers/misc/tspp.c
+++ b/drivers/misc/tspp.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
@@ -25,6 +25,7 @@
 #include <linux/slab.h>          /* kfree, kzalloc */
 #include <linux/ioport.h>        /* XXX_ mem_region */
 #include <linux/dma-mapping.h>   /* dma_XXX */
+#include <linux/dmapool.h>       /* DMA pools */
 #include <linux/delay.h>         /* msleep */
 #include <linux/platform_device.h>
 #include <linux/clk.h>
@@ -65,6 +66,14 @@
 #define TSPP_MAX_BUFFER_SIZE           (32 * 1024 - 1)
 
 /*
+ * Returns whether to use DMA pool for TSPP output buffers.
+ * For buffers smaller than page size, using DMA pool
+ * provides better memory utilization as dma_alloc_coherent
+ * allocates minimum of page size.
+ */
+#define TSPP_USE_DMA_POOL(buff_size)   ((buff_size) < PAGE_SIZE)
+
+/*
  * Max allowed TSPP buffers/descriptors.
  * If SPS desc FIFO holds X descriptors, we can queue up to X-1 descriptors.
  */
@@ -398,6 +407,7 @@
 	void *notify_data;       /* data to be passed with the notifier */
 	u32 expiration_period_ms; /* notification on partially filled buffers */
 	struct timer_list expiration_timer;
+	struct dma_pool *dma_pool;
 	tspp_memfree *memfree;   /* user defined memory free function */
 	void *user_info; /* user cookie passed to memory alloc/free function */
 };
@@ -898,7 +908,7 @@
 }
 
 static int tspp_alloc_buffer(u32 channel_id, struct tspp_data_descriptor *desc,
-	u32 size, tspp_allocator *alloc, void *user)
+	u32 size, struct dma_pool *dma_pool, tspp_allocator *alloc, void *user)
 {
 	if (size < TSPP_MIN_BUFFER_SIZE ||
 		size > TSPP_MAX_BUFFER_SIZE) {
@@ -911,10 +921,15 @@
 		desc->virt_base = alloc(channel_id, size,
 			&desc->phys_base, user);
 	} else {
-		desc->virt_base = dma_alloc_coherent(NULL, size,
-			&desc->phys_base, GFP_KERNEL);
+		if (!dma_pool)
+			desc->virt_base = dma_alloc_coherent(NULL, size,
+				&desc->phys_base, GFP_KERNEL);
+		else
+			desc->virt_base = dma_pool_alloc(dma_pool, GFP_KERNEL,
+				&desc->phys_base);
+
 		if (desc->virt_base == 0) {
-			pr_err("tspp dma alloc coherent failed %i", size);
+			pr_err("tspp: dma buffer allocation failed %i\n", size);
 			return -ENOMEM;
 		}
 	}
@@ -1225,10 +1240,15 @@
 					pbuf->desc.phys_base,
 					channel->user_info);
 			} else {
-				dma_free_coherent(NULL,
-					pbuf->desc.size,
-					pbuf->desc.virt_base,
-					pbuf->desc.phys_base);
+				if (!channel->dma_pool)
+					dma_free_coherent(NULL,
+						pbuf->desc.size,
+						pbuf->desc.virt_base,
+						pbuf->desc.phys_base);
+				else
+					dma_pool_free(channel->dma_pool,
+						pbuf->desc.virt_base,
+						pbuf->desc.phys_base);
 			}
 			pbuf->desc.phys_base = 0;
 		}
@@ -1568,6 +1588,10 @@
 		config->desc.phys_base);
 
 	tspp_destroy_buffers(channel_id, channel);
+	if (channel->dma_pool) {
+		dma_pool_destroy(channel->dma_pool);
+		channel->dma_pool = NULL;
+	}
 
 	channel->src = TSPP_SOURCE_NONE;
 	channel->mode = TSPP_MODE_DISABLED;
@@ -1704,7 +1728,7 @@
 	 */
 	if (channel->buffer_count == 0) {
 		channel->buffer_size =
-			tspp_align_buffer_size_by_mode(channel->buffer_size,
+		tspp_align_buffer_size_by_mode(channel->buffer_size,
 							channel->mode);
 		rc = tspp_allocate_buffers(dev, channel->id,
 					channel->max_buffers,
@@ -2072,6 +2096,7 @@
 	}
 
 	channel = &pdev->channels[channel_id];
+
 	/* allow buffer allocation only if there was no previous buffer
 	 * allocation for this channel.
 	 */
@@ -2101,6 +2126,22 @@
 	channel->memfree = memfree;
 	channel->user_info = user;
 
+	/*
+	 * For small buffers, create a DMA pool so that memory
+	 * is not wasted through dma_alloc_coherent.
+	 */
+	if (TSPP_USE_DMA_POOL(channel->buffer_size)) {
+		channel->dma_pool = dma_pool_create("tspp",
+			NULL, channel->buffer_size, 0, 0);
+		if (!channel->dma_pool) {
+			pr_err("%s: Can't allocate memory pool\n", __func__);
+			return -ENOMEM;
+		}
+	} else {
+		channel->dma_pool = NULL;
+	}
+
+
 	for (channel->buffer_count = 0;
 		channel->buffer_count < channel->max_buffers;
 		channel->buffer_count++) {
@@ -2117,7 +2158,8 @@
 		desc->desc.id = channel->buffer_count;
 		/* allocate the buffer */
 		if (tspp_alloc_buffer(channel_id, &desc->desc,
-			channel->buffer_size, alloc, user) != 0) {
+			channel->buffer_size, channel->dma_pool,
+			alloc, user) != 0) {
 			kfree(desc);
 			pr_warn("%s: Can't allocate buffer %i",
 				__func__, channel->buffer_count);
@@ -2154,6 +2196,11 @@
 		 */
 		tspp_destroy_buffers(channel_id, channel);
 		channel->buffer_count = 0;
+
+		if (channel->dma_pool) {
+			dma_pool_destroy(channel->dma_pool);
+			channel->dma_pool = NULL;
+		}
 		return -ENOMEM;
 	}
 
@@ -2292,8 +2339,10 @@
 		 */
 		if (buffer->read_index == buffer->filled) {
 			buffer->state = TSPP_BUF_STATE_WAITING;
+
 			if (tspp_queue_buffer(channel, buffer))
 				pr_err("tspp: can't submit transfer");
+
 			channel->locked = channel->read;
 			channel->read = channel->read->next;
 		}
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 0f4cc6d..0f9ee46d 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -121,7 +121,8 @@
 	struct device_attribute force_ro;
 	struct device_attribute power_ro_lock;
 	struct device_attribute num_wr_reqs_to_start_packing;
-	struct device_attribute min_sectors_to_check_bkops_status;
+	struct device_attribute bkops_check_threshold;
+	struct device_attribute no_pack_for_random;
 	int	area_type;
 };
 
@@ -331,6 +332,114 @@
 	return ret;
 }
 
+static ssize_t
+bkops_check_threshold_show(struct device *dev,
+				  struct device_attribute *attr, char *buf)
+{
+	struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
+	struct mmc_card *card = md->queue.card;
+	int ret;
+
+	if (!card)
+		ret = -EINVAL;
+	else
+	    ret = snprintf(buf, PAGE_SIZE, "%d\n",
+		card->bkops_info.size_percentage_to_queue_delayed_work);
+
+	mmc_blk_put(md);
+	return ret;
+}
+
+static ssize_t
+bkops_check_threshold_store(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf, size_t count)
+{
+	int value;
+	struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
+	struct mmc_card *card = md->queue.card;
+	unsigned int card_size;
+	int ret = count;
+
+	if (!card) {
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	sscanf(buf, "%d", &value);
+	if ((value <= 0) || (value >= 100)) {
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	card_size = (unsigned int)get_capacity(md->disk);
+	if (card_size <= 0) {
+		ret = -EINVAL;
+		goto exit;
+	}
+	card->bkops_info.size_percentage_to_queue_delayed_work = value;
+	card->bkops_info.min_sectors_to_queue_delayed_work =
+		(card_size * value) / 100;
+
+	pr_debug("%s: size_percentage = %d, min_sectors = %d",
+			mmc_hostname(card->host),
+			card->bkops_info.size_percentage_to_queue_delayed_work,
+			card->bkops_info.min_sectors_to_queue_delayed_work);
+
+exit:
+	mmc_blk_put(md);
+	return count;
+}
+
+static ssize_t
+no_pack_for_random_show(struct device *dev,
+				  struct device_attribute *attr, char *buf)
+{
+	struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
+	int ret;
+
+	ret = snprintf(buf, PAGE_SIZE, "%d\n", md->queue.no_pack_for_random);
+
+	mmc_blk_put(md);
+	return ret;
+}
+
+static ssize_t
+no_pack_for_random_store(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf, size_t count)
+{
+	int value;
+	struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
+	struct mmc_card *card = md->queue.card;
+	int ret = count;
+
+	if (!card) {
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	sscanf(buf, "%d", &value);
+
+	if (value < 0) {
+		pr_err("%s: value %d is not valid. old value remains = %d",
+			mmc_hostname(card->host), value,
+			md->queue.no_pack_for_random);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	md->queue.no_pack_for_random = (value > 0) ?  true : false;
+
+	pr_debug("%s: no_pack_for_random: new value = %d",
+		mmc_hostname(card->host),
+		md->queue.no_pack_for_random);
+
+exit:
+	mmc_blk_put(md);
+	return ret;
+}
+
 static int mmc_blk_open(struct block_device *bdev, fmode_t mode)
 {
 	struct mmc_blk_data *md = mmc_blk_get(bdev->bd_disk);
@@ -958,6 +1067,9 @@
 	from = blk_rq_pos(req);
 	nr = blk_rq_sectors(req);
 
+	if (card->ext_csd.bkops_en)
+		card->bkops_info.sectors_changed += blk_rq_sectors(req);
+
 	if (mmc_can_discard(card))
 		arg = MMC_DISCARD_ARG;
 	else if (mmc_can_trim(card))
@@ -1657,8 +1769,21 @@
 			break;
 		}
 
-		if (rq_data_dir(next) == WRITE)
+		if (mq->no_pack_for_random) {
+			if ((blk_rq_pos(cur) + blk_rq_sectors(cur)) !=
+			    blk_rq_pos(next)) {
+				MMC_BLK_UPDATE_STOP_REASON(stats, RANDOM);
+				put_back = 1;
+				break;
+			}
+		}
+
+		if (rq_data_dir(next) == WRITE) {
 			mq->num_of_potential_packed_wr_reqs++;
+			if (card->ext_csd.bkops_en)
+				card->bkops_info.sectors_changed +=
+					blk_rq_sectors(next);
+		}
 		list_add_tail(&next->queuelist, &mq->mqrq_cur->packed_list);
 		cur = next;
 		reqs++;
@@ -1891,6 +2016,8 @@
 		return 0;
 
 	if (rqc) {
+		if ((card->ext_csd.bkops_en) && (rq_data_dir(rqc) == WRITE))
+			card->bkops_info.sectors_changed += blk_rq_sectors(rqc);
 		reqs = mmc_blk_prep_packed_list(mq, rqc);
 	}
 
@@ -1922,8 +2049,6 @@
 		mmc_queue_bounce_post(mq_rq);
 
 		switch (status) {
-		case MMC_BLK_NEW_REQUEST:
-			BUG(); /* should never get here */
 		case MMC_BLK_SUCCESS:
 		case MMC_BLK_PARTIAL:
 			/*
@@ -1996,6 +2121,11 @@
 			break;
 		case MMC_BLK_NOMEDIUM:
 			goto cmd_abort;
+		default:
+			pr_err("%s:%s: Unhandled return value (%d)",
+					req->rq_disk->disk_name,
+					__func__, status);
+			goto cmd_abort;
 		}
 
 		if (ret) {
@@ -2051,6 +2181,8 @@
 	int ret;
 	struct mmc_blk_data *md = mq->data;
 	struct mmc_card *card = md->queue.card;
+	struct mmc_host *host = card->host;
+	unsigned long flags;
 
 #ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
 	if (mmc_bus_needs_resume(card->host)) {
@@ -2062,11 +2194,8 @@
 	if (req && !mq->mqrq_prev->req) {
 		/* claim host only for the first request */
 		mmc_claim_host(card->host);
-		if (card->ext_csd.bkops_en &&
-		    card->bkops_info.started_delayed_bkops) {
-			card->bkops_info.started_delayed_bkops = false;
+		if (card->ext_csd.bkops_en)
 			mmc_stop_bkops(card);
-		}
 	}
 
 	ret = mmc_blk_part_switch(card, md);
@@ -2101,13 +2230,21 @@
 			mmc_blk_issue_rw_rq(mq, NULL);
 		ret = mmc_blk_issue_flush(mq, req);
 	} else {
+		if (!req && host->areq) {
+			spin_lock_irqsave(&host->context_info.lock, flags);
+			host->context_info.is_waiting_last_req = true;
+			spin_unlock_irqrestore(&host->context_info.lock, flags);
+		}
 		ret = mmc_blk_issue_rw_rq(mq, req);
 	}
 
 out:
-	if (!req && !(mq->flags & MMC_QUEUE_NEW_REQUEST))
+	if (!req && !(mq->flags & MMC_QUEUE_NEW_REQUEST)) {
+		if (mmc_card_need_bkops(card))
+			mmc_start_bkops(card, false);
 		/* release host only when there are no more requests */
 		mmc_release_host(card->host);
+	}
 	return ret;
 }
 
@@ -2126,6 +2263,8 @@
 {
 	struct mmc_blk_data *md;
 	int devidx, ret;
+	unsigned int percentage =
+		BKOPS_SIZE_PERCENTAGE_TO_QUEUE_DELAYED_WORK;
 
 	devidx = find_first_zero_bit(dev_use, max_devices);
 	if (devidx >= max_devices)
@@ -2205,6 +2344,10 @@
 	blk_queue_logical_block_size(md->queue.queue, 512);
 	set_capacity(md->disk, size);
 
+	card->bkops_info.size_percentage_to_queue_delayed_work = percentage;
+	card->bkops_info.min_sectors_to_queue_delayed_work =
+		((unsigned int)size * percentage) / 100;
+
 	if (mmc_host_cmd23(card->host)) {
 		if (mmc_card_mmc(card) ||
 		    (mmc_card_sd(card) &&
@@ -2397,8 +2540,34 @@
 	if (ret)
 		goto num_wr_reqs_to_start_packing_fail;
 
+	md->bkops_check_threshold.show = bkops_check_threshold_show;
+	md->bkops_check_threshold.store = bkops_check_threshold_store;
+	sysfs_attr_init(&md->bkops_check_threshold.attr);
+	md->bkops_check_threshold.attr.name = "bkops_check_threshold";
+	md->bkops_check_threshold.attr.mode = S_IRUGO | S_IWUSR;
+	ret = device_create_file(disk_to_dev(md->disk),
+				 &md->bkops_check_threshold);
+	if (ret)
+		goto bkops_check_threshold_fails;
+
+	md->no_pack_for_random.show = no_pack_for_random_show;
+	md->no_pack_for_random.store = no_pack_for_random_store;
+	sysfs_attr_init(&md->no_pack_for_random.attr);
+	md->no_pack_for_random.attr.name = "no_pack_for_random";
+	md->no_pack_for_random.attr.mode = S_IRUGO | S_IWUSR;
+	ret = device_create_file(disk_to_dev(md->disk),
+				 &md->no_pack_for_random);
+	if (ret)
+		goto no_pack_for_random_fails;
+
 	return ret;
 
+no_pack_for_random_fails:
+	device_remove_file(disk_to_dev(md->disk),
+			   &md->bkops_check_threshold);
+bkops_check_threshold_fails:
+	device_remove_file(disk_to_dev(md->disk),
+			   &md->num_wr_reqs_to_start_packing);
 num_wr_reqs_to_start_packing_fail:
 	device_remove_file(disk_to_dev(md->disk), &md->power_ro_lock);
 power_ro_lock_fail:
diff --git a/drivers/mmc/card/mmc_block_test.c b/drivers/mmc/card/mmc_block_test.c
index 5d571a5..4a21fd4 100644
--- a/drivers/mmc/card/mmc_block_test.c
+++ b/drivers/mmc/card/mmc_block_test.c
@@ -1893,6 +1893,8 @@
 	case BKOPS_DELAYED_WORK_LEVEL_1:
 		bkops_stat->ignore_card_bkops_status = true;
 		card->ext_csd.raw_bkops_status = 1;
+		card->bkops_info.sectors_changed =
+			card->bkops_info.min_sectors_to_queue_delayed_work + 1;
 		mbtd->bkops_stage = BKOPS_STAGE_1;
 
 		__blk_run_queue(q);
@@ -1909,6 +1911,8 @@
 	case BKOPS_DELAYED_WORK_LEVEL_1_HPI:
 		bkops_stat->ignore_card_bkops_status = true;
 		card->ext_csd.raw_bkops_status = 1;
+		card->bkops_info.sectors_changed =
+			card->bkops_info.min_sectors_to_queue_delayed_work + 1;
 		mbtd->bkops_stage = BKOPS_STAGE_1;
 
 		__blk_run_queue(q);
@@ -1937,6 +1941,8 @@
 	case BKOPS_CANCEL_DELAYED_WORK:
 		bkops_stat->ignore_card_bkops_status = true;
 		card->ext_csd.raw_bkops_status = 1;
+		card->bkops_info.sectors_changed =
+			card->bkops_info.min_sectors_to_queue_delayed_work + 1;
 		mbtd->bkops_stage = BKOPS_STAGE_1;
 
 		__blk_run_queue(q);
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index dc27db6..9babeab 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -78,14 +78,6 @@
 		set_current_state(TASK_INTERRUPTIBLE);
 		req = blk_fetch_request(q);
 		mq->mqrq_cur->req = req;
-		if (!req && mq->mqrq_prev->req &&
-			!(mq->mqrq_prev->req->cmd_flags & REQ_SANITIZE) &&
-			!(mq->mqrq_prev->req->cmd_flags & REQ_FLUSH) &&
-			!(mq->mqrq_prev->req->cmd_flags & REQ_DISCARD)) {
-			card->host->context_info.is_waiting_last_req = true;
-			if (stats && stats->enabled)
-				stats->null_fetched++;
-		}
 		spin_unlock_irq(q->queue_lock);
 
 		if (req || mq->mqrq_prev->req) {
@@ -97,6 +89,16 @@
 					stats->fetch_due_to_new_req++;
 				continue; /* fetch again */
 			}
+
+			/*
+			 * Current request becomes previous request
+			 * and vice versa.
+			 */
+			mq->mqrq_prev->brq.mrq.data = NULL;
+			mq->mqrq_prev->req = NULL;
+			tmp = mq->mqrq_prev;
+			mq->mqrq_prev = mq->mqrq_cur;
+			mq->mqrq_cur = tmp;
 		} else {
 			if (kthread_should_stop()) {
 				set_current_state(TASK_RUNNING);
@@ -107,13 +109,6 @@
 			schedule();
 			down(&mq->thread_sem);
 		}
-
-		/* Current request becomes previous request and vice versa. */
-		mq->mqrq_prev->brq.mrq.data = NULL;
-		mq->mqrq_prev->req = NULL;
-		tmp = mq->mqrq_prev;
-		mq->mqrq_prev = mq->mqrq_cur;
-		mq->mqrq_cur = tmp;
 	} while (1);
 	up(&mq->thread_sem);
 
diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h
index 0a72372..119b0c7 100644
--- a/drivers/mmc/card/queue.h
+++ b/drivers/mmc/card/queue.h
@@ -51,6 +51,7 @@
 	bool			wr_packing_enabled;
 	int			num_of_potential_packed_wr_reqs;
 	int			num_wr_reqs_to_start_packing;
+	bool			no_pack_for_random;
 	int (*err_check_fn) (struct mmc_card *, struct mmc_async_req *);
 	void (*packed_test_fn) (struct request_queue *, struct mmc_queue_req *);
 };
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index f598e63..65f748f 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -357,6 +357,10 @@
 	if (!card || !card->ext_csd.bkops_en || mmc_card_doing_bkops(card))
 		return;
 
+	if (card->bkops_info.sectors_changed <
+	    card->bkops_info.min_sectors_to_queue_delayed_work)
+		return;
+
 	pr_debug("%s: %s: queueing delayed_bkops_work\n",
 		 mmc_hostname(card->host), __func__);
 
@@ -366,7 +370,6 @@
 	 * it was removed from the queue work but not started yet
 	 */
 	card->bkops_info.cancel_delayed_work = false;
-	card->bkops_info.started_delayed_bkops = true;
 	queue_delayed_work(system_nrt_wq, &card->bkops_info.dw,
 			   msecs_to_jiffies(
 				   card->bkops_info.delay_ms));
@@ -386,8 +389,6 @@
 void mmc_start_bkops(struct mmc_card *card, bool from_exception)
 {
 	int err;
-	int timeout;
-	bool use_busy_signal;
 
 	BUG_ON(!card);
 	if (!card->ext_csd.bkops_en)
@@ -408,43 +409,45 @@
 		goto out;
 	}
 
-	err = mmc_read_bkops_status(card);
-	if (err) {
-		pr_err("%s: %s: Failed to read bkops status: %d\n",
-		       mmc_hostname(card->host), __func__, err);
+	if (from_exception && mmc_card_need_bkops(card))
 		goto out;
-	}
-
-	if (!card->ext_csd.raw_bkops_status)
-		goto out;
-
-	pr_info("%s: %s: card->ext_csd.raw_bkops_status = 0x%x\n",
-		mmc_hostname(card->host), __func__,
-		card->ext_csd.raw_bkops_status);
 
 	/*
-	 * If the function was called due to exception but there is no need
-	 * for urgent BKOPS, BKOPs will be performed by the delayed BKOPs
-	 * work, before going to suspend
+	 * If the need BKOPS flag is set, there is no need to check if BKOPS
+	 * is needed since we already know that it does
 	 */
-	if (card->ext_csd.raw_bkops_status < EXT_CSD_BKOPS_LEVEL_2 &&
-	    from_exception) {
-		pr_debug("%s: %s: Level 1 from exception, exit",
-			 mmc_hostname(card->host), __func__);
+	if (!mmc_card_need_bkops(card)) {
+		err = mmc_read_bkops_status(card);
+		if (err) {
+			pr_err("%s: %s: Failed to read bkops status: %d\n",
+			       mmc_hostname(card->host), __func__, err);
+			goto out;
+		}
+
+		if (!card->ext_csd.raw_bkops_status)
+			goto out;
+
+		pr_info("%s: %s: raw_bkops_status=0x%x, from_exception=%d\n",
+			mmc_hostname(card->host), __func__,
+			card->ext_csd.raw_bkops_status,
+			from_exception);
+	}
+
+	/*
+	 * If the function was called due to exception, BKOPS will be performed
+	 * after handling the last pending request
+	 */
+	if (from_exception) {
+		pr_debug("%s: %s: Level %d from exception, exit",
+			 mmc_hostname(card->host), __func__,
+			 card->ext_csd.raw_bkops_status);
+		mmc_card_set_need_bkops(card);
 		goto out;
 	}
-
-	if (card->ext_csd.raw_bkops_status >= EXT_CSD_BKOPS_LEVEL_2) {
-		timeout = MMC_BKOPS_MAX_TIMEOUT;
-		use_busy_signal = true;
-	} else {
-		timeout = 0;
-		use_busy_signal = false;
-	}
+	pr_info("%s: %s: Starting bkops\n", mmc_hostname(card->host), __func__);
 
 	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-			   EXT_CSD_BKOPS_START, 1, timeout,
-			   use_busy_signal, use_busy_signal);
+			EXT_CSD_BKOPS_START, 1, 0, false, false);
 	if (err) {
 		pr_warn("%s: %s: Error %d when starting bkops\n",
 			mmc_hostname(card->host), __func__, err);
@@ -452,19 +455,13 @@
 	}
 	MMC_UPDATE_STATS_BKOPS_SEVERITY_LEVEL(card->bkops_info.bkops_stats,
 					card->ext_csd.raw_bkops_status);
+	mmc_card_clr_need_bkops(card);
 
-	/*
-	 * For urgent bkops status (LEVEL_2 and more)
-	 * bkops executed synchronously, otherwise
-	 * the operation is in progress
-	 */
-	if (!use_busy_signal) {
-		mmc_card_set_doing_bkops(card);
-		pr_debug("%s: %s: starting the polling thread\n",
-			 mmc_hostname(card->host), __func__);
-		queue_work(system_nrt_wq,
-			   &card->bkops_info.poll_for_completion);
-	}
+	mmc_card_set_doing_bkops(card);
+	pr_debug("%s: %s: starting the polling thread\n",
+		 mmc_hostname(card->host), __func__);
+	queue_work(system_nrt_wq,
+		   &card->bkops_info.poll_for_completion);
 
 out:
 	mmc_release_host(card->host);
@@ -518,7 +515,7 @@
 			pr_debug("%s: %s: completed BKOPs, exit polling\n",
 				 mmc_hostname(card->host), __func__);
 			mmc_card_clr_doing_bkops(card);
-			card->bkops_info.started_delayed_bkops = false;
+			card->bkops_info.sectors_changed = 0;
 			goto out;
 		}
 
@@ -531,8 +528,12 @@
 		msleep(BKOPS_COMPLETION_POLLING_INTERVAL_MS);
 	} while (time_before(jiffies, timeout_jiffies));
 
-	pr_err("%s: %s: exit polling due to timeout\n",
+	pr_err("%s: %s: exit polling due to timeout, stop bkops\n",
 	       mmc_hostname(card->host), __func__);
+	err = mmc_stop_bkops(card);
+	if (err)
+		pr_err("%s: %s: mmc_stop_bkops failed, err=%d\n",
+			       mmc_hostname(card->host), __func__, err);
 
 	return;
 out:
@@ -622,7 +623,8 @@
  * Returns enum mmc_blk_status after checking errors.
  */
 static int mmc_wait_for_data_req_done(struct mmc_host *host,
-				      struct mmc_request *mrq)
+				      struct mmc_request *mrq,
+				      struct mmc_async_req *next_req)
 {
 	struct mmc_command *cmd;
 	struct mmc_context_info *context_info = &host->context_info;
@@ -664,8 +666,10 @@
 			context_info->is_new_req = false;
 			if (stats->enabled)
 				stats->new_request_flag++;
-			err = MMC_BLK_NEW_REQUEST;
-			break; /* return err */
+			if (!next_req) {
+				err = MMC_BLK_NEW_REQUEST;
+				break; /* return err */
+			}
 		}
 	} /* while */
 	return err;
@@ -778,13 +782,9 @@
 		mmc_pre_req(host, areq->mrq, !host->areq);
 
 	if (host->areq) {
-		err = mmc_wait_for_data_req_done(host, host->areq->mrq);
+		err = mmc_wait_for_data_req_done(host, host->areq->mrq,
+				areq);
 		if (err == MMC_BLK_NEW_REQUEST) {
-			if (areq) {
-				pr_err("%s: new request while areq = %p",
-						mmc_hostname(host), areq);
-				BUG_ON(1);
-			}
 			if (error)
 				*error = err;
 			/*
@@ -936,7 +936,9 @@
  *	Send HPI command to stop ongoing background operations to
  *	allow rapid servicing of foreground operations, e.g. read/
  *	writes. Wait until the card comes out of the programming state
- *	to avoid errors in servicing read/write requests.
+ *      to avoid errors in servicing read/write requests.
+ *
+ *      The function should be called with host claimed.
  */
 int mmc_stop_bkops(struct mmc_card *card)
 {
@@ -3061,6 +3063,7 @@
  * Turn the cache ON/OFF.
  * Turning the cache OFF shall trigger flushing of the data
  * to the non-volatile storage.
+ * This function should be called with host claimed
  */
 int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
 {
@@ -3072,9 +3075,6 @@
 			mmc_card_is_removable(host))
 		return err;
 
-	if (!mmc_try_claim_host(host))
-		return -EBUSY;
-
 	if (card && mmc_card_mmc(card) &&
 			(card->ext_csd.cache_size > 0)) {
 		enable = !!enable;
@@ -3092,7 +3092,6 @@
 				card->ext_csd.cache_ctrl = enable;
 		}
 	}
-	mmc_release_host(host);
 
 	return err;
 }
@@ -3114,9 +3113,6 @@
 	if (cancel_delayed_work(&host->detect))
 		wake_unlock(&host->detect_wake_lock);
 	mmc_flush_scheduled_work();
-	err = mmc_cache_ctrl(host, 0);
-	if (err)
-		goto out;
 
 	mmc_bus_get(host);
 	if (host->bus_ops && !host->bus_dead) {
@@ -3174,7 +3170,6 @@
 	if (!err && !mmc_card_keep_power(host))
 		mmc_power_off(host);
 
-out:
 	return err;
 stop_bkops_err:
 	if (!(host->card && mmc_card_sdio(host->card)))
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index ae8a619..d91bc31 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -484,6 +484,13 @@
 			pack_stats->pack_stop_reason[LARGE_SEC_ALIGN]);
 		strlcat(ubuf, temp_buf, cnt);
 	}
+	if (pack_stats->pack_stop_reason[RANDOM]) {
+		snprintf(temp_buf, TEMP_BUF_SIZE,
+			 "%s: %d times: random request\n",
+			mmc_hostname(card->host),
+			pack_stats->pack_stop_reason[RANDOM]);
+		strlcat(ubuf, temp_buf, cnt);
+	}
 
 	spin_unlock(&pack_stats->lock);
 
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index 751ba75..0cfddc4 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -33,6 +33,7 @@
 static void mmc_host_classdev_release(struct device *dev)
 {
 	struct mmc_host *host = cls_dev_to_mmc_host(dev);
+	kfree(host->wlock_name);
 	kfree(host);
 }
 
@@ -337,8 +338,10 @@
 
 	spin_lock_init(&host->lock);
 	init_waitqueue_head(&host->wq);
+	host->wlock_name = kasprintf(GFP_KERNEL,
+			"%s_detect", mmc_hostname(host));
 	wake_lock_init(&host->detect_wake_lock, WAKE_LOCK_SUSPEND,
-		kasprintf(GFP_KERNEL, "%s_detect", mmc_hostname(host)));
+			host->wlock_name);
 	INIT_DELAYED_WORK(&host->detect, mmc_rescan);
 #ifdef CONFIG_PM
 	host->pm_notify.notifier_call = mmc_pm_notify;
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index f3653b8..ec30cad 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1402,17 +1402,16 @@
 
 			/*
 			 * Calculate the time to start the BKOPs checking.
-			 * The idle time of the host controller should be taken
-			 * into account in order to prevent a race condition
-			 * before starting BKOPs and going into suspend.
-			 * If the host controller didn't set its idle time,
+			 * The host controller can set this time in order to
+			 * prevent a race condition before starting BKOPs
+			 * and going into suspend.
+			 * If the host controller didn't set this time,
 			 * a default value is used.
 			 */
 			card->bkops_info.delay_ms = MMC_IDLE_BKOPS_TIME_MS;
-			if (card->bkops_info.host_suspend_tout_ms)
-				card->bkops_info.delay_ms = min(
-					card->bkops_info.delay_ms,
-				      card->bkops_info.host_suspend_tout_ms/2);
+			if (card->bkops_info.host_delay_ms)
+				card->bkops_info.delay_ms =
+					card->bkops_info.host_delay_ms;
 		}
 	}
 
@@ -1530,6 +1529,11 @@
 	mmc_disable_clk_scaling(host);
 
 	mmc_claim_host(host);
+
+	err = mmc_cache_ctrl(host, 0);
+	if (err)
+		goto out;
+
 	if (mmc_can_poweroff_notify(host->card))
 		err = mmc_poweroff_notify(host->card, EXT_CSD_POWER_OFF_SHORT);
 	else if (mmc_card_can_sleep(host))
@@ -1537,8 +1541,9 @@
 	else if (!mmc_host_is_spi(host))
 		mmc_deselect_cards(host);
 	host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
-	mmc_release_host(host);
 
+out:
+	mmc_release_host(host);
 	return err;
 }
 
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index f1ba8ad..91720ee 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -236,14 +236,6 @@
 {
 	int rc;
 
-	/* Reset and init DML */
-	rc = msmsdcc_dml_init(host);
-	if (rc) {
-		pr_err("%s: msmsdcc_dml_init error=%d\n",
-				mmc_hostname(host->mmc), rc);
-		goto out;
-	}
-
 	/* Reset all SDCC BAM pipes */
 	rc = msmsdcc_sps_reset_ep(host, &host->sps.prod);
 	if (rc) {
@@ -276,13 +268,21 @@
 	}
 
 	rc = msmsdcc_sps_restore_ep(host, &host->sps.cons);
-	if (rc)
+	if (rc) {
 		pr_err("%s: msmsdcc_sps_restore_ep(cons) error=%d\n",
 				mmc_hostname(host->mmc), rc);
-	else
-		host->sps.reset_bam = false;
+		goto out;
+	}
+
+	/* Reset and init DML */
+	rc = msmsdcc_dml_init(host);
+	if (rc)
+		pr_err("%s: msmsdcc_dml_init error=%d\n",
+				mmc_hostname(host->mmc), rc);
 
 out:
+	if (!rc)
+		host->sps.reset_bam = false;
 	return rc;
 }
 
diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c
index 52bdae1..a808e0b 100644
--- a/drivers/platform/msm/usb_bam.c
+++ b/drivers/platform/msm/usb_bam.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
@@ -387,6 +387,9 @@
 int usb_bam_connect(u8 idx, u32 *src_pipe_idx, u32 *dst_pipe_idx)
 {
 	struct usb_bam_connect_info *connection = &usb_bam_connections[idx];
+	struct msm_usb_bam_platform_data *pdata =
+				usb_bam_pdev->dev.platform_data;
+	int usb_active_bam = pdata->usb_active_bam;
 	int ret;
 
 	if (!usb_bam_pdev) {
@@ -409,6 +412,10 @@
 	connection->dst_pipe = dst_pipe_idx;
 	connection->idx = idx;
 
+	/* Check if BAM requires RESET before connect */
+	if (pdata->reset_on_connect[usb_active_bam] == true)
+		sps_device_reset(h_bam);
+
 	if (src_pipe_idx) {
 		/* open USB -> Peripheral pipe */
 		ret = connect_pipe(connection->idx, USB_TO_PEER_PERIPHERAL,
@@ -899,6 +906,7 @@
 	u32 pipe_entry = 0;
 	char *key = NULL;
 	enum usb_pipe_mem_type mem_type;
+	bool reset_bam;
 
 	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata) {
@@ -985,6 +993,10 @@
 			pr_err("Cannot read string\n");
 			goto err;
 		}
+		reset_bam = of_property_read_bool(node,
+					"qcom,reset-bam-on-connect");
+		if (reset_bam)
+			pdata->reset_on_connect[bam] = true;
 
 		if (strnstr(str, "usb-to", 30))
 			dir = USB_TO_PEER_PERIPHERAL;
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index f6591c3d..ed57f2c 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -160,6 +160,8 @@
 	int			soc_calc_period;
 	int			normal_voltage_calc_ms;
 	int			low_voltage_calc_ms;
+	int			imax_ua;
+	struct wake_lock	soc_wake_lock;
 };
 
 /*
@@ -728,8 +730,9 @@
  * CC_RESOLUTION_N, CC_RESOLUTION_D, CC_READING_TICKS
  * and rsense
  */
-#define CC_RAW_5MAH	0x00110000
-#define MIN_OCV_UV	2000000
+#define CC_RAW_5MAH		0x00110000
+#define MIN_OCV_UV		2000000
+#define OCV_RAW_UNINITIALIZED	0xFFFF
 static int read_soc_params_raw(struct pm8921_bms_chip *chip,
 				struct pm8921_soc_params *raw,
 				int batt_temp_decidegc)
@@ -749,7 +752,7 @@
 
 	usb_chg =  usb_chg_plugged_in(chip);
 
-	if (chip->prev_last_good_ocv_raw == 0) {
+	if (chip->prev_last_good_ocv_raw == OCV_RAW_UNINITIALIZED) {
 		chip->prev_last_good_ocv_raw = raw->last_good_ocv_raw;
 
 		convert_vbatt_raw_to_uv(chip, usb_chg,
@@ -801,7 +804,7 @@
 
 	/* fake a high OCV if we are just done charging */
 	if (chip->ocv_reading_at_100 != raw->last_good_ocv_raw) {
-		chip->ocv_reading_at_100 = 0;
+		chip->ocv_reading_at_100 = OCV_RAW_UNINITIALIZED;
 		chip->cc_reading_at_100 = 0;
 	} else {
 		/*
@@ -1025,28 +1028,34 @@
 	return uuc;
 }
 
+#define TIME_PER_PERCENT_UUC			60
 static int adjust_uuc(struct pm8921_bms_chip *chip, int fcc_uah,
 			int new_pc_unusable,
 			int new_uuc,
 			int batt_temp,
 			int rbatt,
-			int *iavg_ma)
+			int *iavg_ma,
+			int delta_time_s)
 {
 	int new_unusable_mv;
 	int batt_temp_degc = batt_temp / 10;
+	int max_percent_change;
+
+	max_percent_change = max(delta_time_s / TIME_PER_PERCENT_UUC, 1);
 
 	if (chip->prev_pc_unusable == -EINVAL
-		|| abs(chip->prev_pc_unusable - new_pc_unusable) <= 1) {
+		|| abs(chip->prev_pc_unusable - new_pc_unusable)
+			<= max_percent_change) {
 		chip->prev_pc_unusable = new_pc_unusable;
 		return new_uuc;
 	}
 
 	/* the uuc is trying to change more than 1% restrict it */
 	if (new_pc_unusable > chip->prev_pc_unusable)
-		chip->prev_pc_unusable++;
+		chip->prev_pc_unusable += max_percent_change;
 	else
-		chip->prev_pc_unusable--;
-
+		chip->prev_pc_unusable -= max_percent_change;
+	chip->prev_pc_unusable = clamp(chip->prev_pc_unusable, 0, 100);
 	new_uuc = (fcc_uah * chip->prev_pc_unusable) / 100;
 
 	/* also find update the iavg_ma accordingly */
@@ -1096,57 +1105,58 @@
 	return 0;
 }
 
-static void calculate_iavg_ua(struct pm8921_bms_chip *chip, int cc_uah,
-				int *iavg_ua, int *delta_time_s)
+static int calculate_delta_time(struct pm8921_bms_chip *chip, int *delta_time_s)
 {
-	int delta_cc_uah;
 	unsigned long now_tm_sec = 0;
-	int rc = 0;
+
+	/* default to delta time = 0 if anything fails */
+	*delta_time_s = 0;
+
+	get_current_time(&now_tm_sec);
+
+	*delta_time_s = (now_tm_sec - chip->tm_sec);
+	pr_debug("tm_sec = %ld, now_tm_sec = %ld delta_s = %d\n",
+		chip->tm_sec, now_tm_sec, *delta_time_s);
+
+	/* remember this time */
+	chip->tm_sec = now_tm_sec;
+	return 0;
+}
+
+static void calculate_iavg_ua(struct pm8921_bms_chip *chip, int cc_uah,
+				int *iavg_ua, int delta_time_s)
+{
+	int delta_cc_uah = 0;
 
 	/* if anything fails report the previous iavg_ua */
 	*iavg_ua = chip->prev_iavg_ua;
 
-	rc = get_current_time(&now_tm_sec);
-	if (rc) {
-		pr_err("Could not get current time: %d\n", rc);
-		goto out;
-	}
-
-	if (chip->tm_sec == 0) {
-		*delta_time_s = 0;
+	if (chip->last_cc_uah == INT_MIN) {
 		pm8921_bms_get_battery_current(iavg_ua);
 		goto out;
 	}
 
-	*delta_time_s = (now_tm_sec - chip->tm_sec);
-
 	/* use the previous iavg if called within 15 seconds */
-	if (*delta_time_s < 15) {
+	if (delta_time_s < 15) {
 		*iavg_ua = chip->prev_iavg_ua;
 		goto out;
 	}
 
 	delta_cc_uah = cc_uah - chip->last_cc_uah;
 
-	*iavg_ua = div_s64((s64)delta_cc_uah * 3600, *delta_time_s);
-
-	pr_debug("tm_sec = %ld, now_tm_sec = %ld delta_s = %d delta_cc = %d iavg_ua = %d\n",
-				chip->tm_sec, now_tm_sec,
-				*delta_time_s, delta_cc_uah, (int)*iavg_ua);
+	*iavg_ua = div_s64((s64)delta_cc_uah * 3600, delta_time_s);
 
 out:
+	pr_debug("delta_cc = %d iavg_ua = %d\n", delta_cc_uah, (int)*iavg_ua);
 	/* remember the iavg */
 	chip->prev_iavg_ua = *iavg_ua;
 
 	/* remember cc_uah */
 	chip->last_cc_uah = cc_uah;
-
-	/* remember this time */
-	chip->tm_sec = now_tm_sec;
 }
 
 #define IAVG_SAMPLES 16
-#define CHARGING_IAVG_MA 250
+#define MIN_IAVG_MA 250
 #define MIN_SECONDS_FOR_VALID_SAMPLE	20
 static int calculate_unusable_charge_uah(struct pm8921_bms_chip *chip,
 				int rbatt, int fcc_uah, int cc_uah,
@@ -1180,8 +1190,8 @@
 	 * if we are charging use a nominal avg current so that we keep
 	 * a reasonable UUC while charging
 	 */
-	if (iavg_ma < 0)
-		iavg_ma = CHARGING_IAVG_MA;
+	if (iavg_ma < MIN_IAVG_MA)
+		iavg_ma = MIN_IAVG_MA;
 	iavg_samples[iavg_index] = iavg_ma;
 	iavg_index = (iavg_index + 1) % IAVG_SAMPLES;
 	iavg_num_samples++;
@@ -1205,9 +1215,9 @@
 					&pc_unusable);
 	pr_debug("iavg = %d uuc_iavg = %d\n", iavg_ma, uuc_uah_iavg);
 
-	/* restrict the uuc such that it can increase only by one percent */
+	/* restrict the uuc change to one percent per 60 seconds */
 	uuc_uah_iavg = adjust_uuc(chip, fcc_uah, pc_unusable, uuc_uah_iavg,
-					batt_temp, rbatt, &iavg_ma);
+				batt_temp, rbatt, &iavg_ma, delta_time_s);
 
 	/* find out what the avg current should be for this uuc */
 	chip->prev_uuc_iavg_ma = iavg_ma;
@@ -1239,11 +1249,17 @@
 						int *remaining_charge_uah,
 						int *cc_uah,
 						int *rbatt,
-						int *iavg_ua,
-						int *delta_time_s)
+						int *iavg_ua)
 {
 	int soc_rbatt;
+	int delta_time_s;
+	int rc;
 
+	rc = calculate_delta_time(chip, &delta_time_s);
+	if (rc) {
+		pr_err("Failed to get delta time from RTC: %d\n", rc);
+		delta_time_s = 0;
+	}
 	*fcc_uah = calculate_fcc_uah(chip, batt_temp, chargecycles);
 	pr_debug("FCC = %uuAh batt_temp = %d, cycles = %d\n",
 					*fcc_uah, batt_temp, chargecycles);
@@ -1271,7 +1287,7 @@
 	*unusable_charge_uah = calculate_unusable_charge_uah(chip, *rbatt,
 					*fcc_uah, *cc_uah, soc_rbatt,
 					batt_temp, chargecycles, *iavg_ua,
-					*delta_time_s);
+					delta_time_s);
 	pr_debug("UUC = %uuAh\n", *unusable_charge_uah);
 }
 
@@ -1286,7 +1302,6 @@
 	int real_fcc_uah;
 	int rbatt;
 	int iavg_ua;
-	int delta_time_s;
 
 	calculate_soc_params(chip, raw, batt_temp, chargecycles,
 						&fcc_uah,
@@ -1294,8 +1309,7 @@
 						&remaining_charge_uah,
 						&cc_uah,
 						&rbatt,
-						&iavg_ua,
-						&delta_time_s);
+						&iavg_ua);
 
 	real_fcc_uah = remaining_charge_uah - cc_uah;
 	*ret_fcc_uah = fcc_uah;
@@ -1406,6 +1420,13 @@
 	*ret_rc = rc_uah;
 	*ret_uuc = uuc_uah;
 }
+
+static void calc_current_max(struct pm8921_bms_chip *chip, int ocv_uv,
+		int rbatt_mohm)
+{
+	chip->imax_ua = 1000 * (ocv_uv - chip->v_cutoff * 1000) / rbatt_mohm;
+}
+
 static int bound_soc(int soc)
 {
 	soc = max(0, soc);
@@ -1533,6 +1554,7 @@
 	delta_ocv_uv_limit = DIV_ROUND_CLOSEST(ibat_ua, 1000);
 
 	ocv_est_uv = vbat_uv + (ibat_ua * rbatt)/1000;
+	calc_current_max(chip, ocv_est_uv, rbatt);
 	pc_est = calculate_pc(chip, ocv_est_uv, batt_temp, last_chargecycles);
 	soc_est = div_s64((s64)fcc_uah * pc_est - uuc_uah*100,
 						(s64)fcc_uah - uuc_uah);
@@ -1903,7 +1925,6 @@
 	int cc_uah;
 	int rbatt;
 	int iavg_ua;
-	int delta_time_s;
 	int new_ocv;
 	int new_rc_uah;
 	int new_ucc_uah;
@@ -1919,8 +1940,7 @@
 						&remaining_charge_uah,
 						&cc_uah,
 						&rbatt,
-						&iavg_ua,
-						&delta_time_s);
+						&iavg_ua);
 
 	/* calculate remaining usable charge */
 	remaining_usable_charge_uah = remaining_charge_uah
@@ -2047,6 +2067,7 @@
 	struct pm8921_soc_params raw;
 	int soc;
 
+	wake_lock(&the_chip->soc_wake_lock);
 	get_batt_temp(chip, &batt_temp);
 
 	mutex_lock(&chip->last_ocv_uv_mutex);
@@ -2055,6 +2076,7 @@
 	soc = calculate_state_of_charge(chip, &raw,
 					batt_temp, last_chargecycles);
 	mutex_unlock(&chip->last_ocv_uv_mutex);
+	wake_unlock(&the_chip->soc_wake_lock);
 	return soc;
 }
 
@@ -2241,42 +2263,15 @@
 }
 EXPORT_SYMBOL_GPL(pm8921_bms_get_percent_charge);
 
-int pm8921_bms_get_rbatt(void)
+int pm8921_bms_get_current_max(void)
 {
-	int batt_temp;
-	struct pm8921_soc_params raw;
-	int fcc_uah;
-	int unusable_charge_uah;
-	int remaining_charge_uah;
-	int cc_uah;
-	int rbatt;
-	int iavg_ua;
-	int delta_time_s;
-
 	if (!the_chip) {
 		pr_err("called before initialization\n");
 		return -EINVAL;
 	}
-
-	get_batt_temp(the_chip, &batt_temp);
-
-	mutex_lock(&the_chip->last_ocv_uv_mutex);
-
-	read_soc_params_raw(the_chip, &raw, batt_temp);
-
-	calculate_soc_params(the_chip, &raw, batt_temp, last_chargecycles,
-						&fcc_uah,
-						&unusable_charge_uah,
-						&remaining_charge_uah,
-						&cc_uah,
-						&rbatt,
-						&iavg_ua,
-						&delta_time_s);
-	mutex_unlock(&the_chip->last_ocv_uv_mutex);
-
-	return rbatt;
+	return the_chip->imax_ua;
 }
-EXPORT_SYMBOL_GPL(pm8921_bms_get_rbatt);
+EXPORT_SYMBOL_GPL(pm8921_bms_get_current_max);
 
 int pm8921_bms_get_fcc(void)
 {
@@ -3018,6 +3013,9 @@
 	chip->rconn_mohm = pdata->rconn_mohm;
 	chip->start_percent = -EINVAL;
 	chip->end_percent = -EINVAL;
+	chip->last_cc_uah = INT_MIN;
+	chip->ocv_reading_at_100 = OCV_RAW_UNINITIALIZED;
+	chip->prev_last_good_ocv_raw = OCV_RAW_UNINITIALIZED;
 	chip->shutdown_soc_valid_limit = pdata->shutdown_soc_valid_limit;
 	chip->adjust_soc_low_threshold = pdata->adjust_soc_low_threshold;
 
@@ -3031,6 +3029,7 @@
 
 	chip->prev_pc_unusable = -EINVAL;
 	chip->soc_at_cv = -EINVAL;
+	chip->imax_ua = -EINVAL;
 
 	chip->ignore_shutdown_soc = pdata->ignore_shutdown_soc;
 	rc = set_battery_data(chip);
@@ -3063,10 +3062,12 @@
 	INIT_DELAYED_WORK(&chip->calculate_soc_delayed_work,
 			calculate_soc_work);
 
+	wake_lock_init(&chip->soc_wake_lock,
+			WAKE_LOCK_SUSPEND, "pm8921_soc_lock");
 	rc = request_irqs(chip, pdev);
 	if (rc) {
 		pr_err("couldn't register interrupts rc = %d\n", rc);
-		goto free_chip;
+		goto destroy_soc_wl;
 	}
 
 	wake_lock_init(&chip->low_voltage_wake_lock,
@@ -3108,7 +3109,10 @@
 	return 0;
 
 free_irqs:
+	wake_lock_destroy(&chip->low_voltage_wake_lock);
 	free_irqs(chip);
+destroy_soc_wl:
+	wake_lock_destroy(&chip->soc_wake_lock);
 free_chip:
 	kfree(chip);
 	return rc;
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index c86ba9e..a09e5ee 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -1663,32 +1663,7 @@
 
 static int get_prop_batt_current_max(struct pm8921_chg_chip *chip)
 {
-	int rbatt, ibatt_ua, vbatt_uv, ocv_uv;
-	int imax_ma;
-	int rc;
-
-	rbatt = pm8921_bms_get_rbatt();
-
-	if (rbatt < 0) {
-		rc = -ENXIO;
-		return rc;
-	}
-
-	rc =  pm8921_bms_get_simultaneous_battery_voltage_and_current
-			(&ibatt_ua, &vbatt_uv);
-
-	if (rc)
-		return rc;
-
-	ocv_uv = vbatt_uv + ibatt_ua*rbatt/1000;
-
-	imax_ma = (ocv_uv - chip->min_voltage_mv*1000)/rbatt;
-
-	if (imax_ma < 0)
-		imax_ma = 0;
-
-	return imax_ma*1000;
-
+	return pm8921_bms_get_current_max();
 }
 
 static int get_prop_batt_current(struct pm8921_chg_chip *chip)
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index 4ffe0d8..2d73af6 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -3,7 +3,7 @@
  * MSM 7k High speed uart driver
  *
  * Copyright (c) 2008 Google Inc.
- * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2013, The Linux Foundation. All rights reserved.
  * Modified: Nick Pelly <npelly@google.com>
  *
  * All source code in this file is licensed under the following license
@@ -754,7 +754,7 @@
 
 	uport->ignore_status_mask = termios->c_iflag & INPCK;
 	uport->ignore_status_mask |= termios->c_iflag & IGNPAR;
-	uport->ignore_status_mask = termios->c_iflag & IGNBRK;
+	uport->ignore_status_mask |= termios->c_iflag & IGNBRK;
 
 	uport->read_status_mask = (termios->c_cflag & CREAD);
 
diff --git a/drivers/tty/serial/msm_serial_hs_hwreg.h b/drivers/tty/serial/msm_serial_hs_hwreg.h
index 8debc36..20d6781 100644
--- a/drivers/tty/serial/msm_serial_hs_hwreg.h
+++ b/drivers/tty/serial/msm_serial_hs_hwreg.h
@@ -1,6 +1,6 @@
 /* drivers/serial/msm_serial_hs_hwreg.h
  *
- * Copyright (c) 2007-2009, 2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2009, 2012-2013,The Linux Foundation. All rights reserved.
  * 
  * All source code in this file is licensed under the following license
  * except where indicated.
@@ -59,8 +59,16 @@
 #define UARTDM_MR1_ADDR 0x0
 #define UARTDM_MR2_ADDR 0x4
 
+/* Backward Compatability Register for UARTDM Core v1.4 */
+#define UARTDM_BCR_ADDR	0xc8
+
+/*
+ * UARTDM Core v1.4 STALE_IRQ_EMPTY bit defination
+ * Stale interrupt will fire if bit is set when RX-FIFO is empty
+ */
+#define UARTDM_BCR_STALE_IRQ_EMPTY	0x2
+
 /* write only register */
-#define UARTDM_CSR_ADDR    0x8
 #define UARTDM_CSR_115200 0xFF
 #define UARTDM_CSR_57600  0xEE
 #define UARTDM_CSR_38400  0xDD
@@ -79,22 +87,11 @@
 #define UARTDM_CSR_75     0x00
 
 /* write only register */
-#define UARTDM_TF_ADDR 0x70
-#define UARTDM_TF2_ADDR 0x74
-#define UARTDM_TF3_ADDR 0x78
-#define UARTDM_TF4_ADDR 0x7C
-
-/* write only register */
-#define UARTDM_CR_ADDR 0x10
-/* write only register */
-#define UARTDM_IMR_ADDR 0x14
-
 #define UARTDM_IPR_ADDR 0x18
 #define UARTDM_TFWR_ADDR 0x1c
 #define UARTDM_RFWR_ADDR 0x20
 #define UARTDM_HCR_ADDR 0x24
 #define UARTDM_DMRX_ADDR 0x34
-#define UARTDM_IRDA_ADDR 0x38
 #define UARTDM_DMEN_ADDR 0x3c
 
 /* UART_DM_NO_CHARS_FOR_TX */
@@ -105,21 +102,6 @@
 #define UARTDM_SIM_CFG_ADDR 0x80
 
 /* Read Only register */
-#define UARTDM_SR_ADDR 0x8
-
-/* Read Only register */
-#define UARTDM_RF_ADDR  0x70
-#define UARTDM_RF2_ADDR 0x74
-#define UARTDM_RF3_ADDR 0x78
-#define UARTDM_RF4_ADDR 0x7C
-
-/* Read Only register */
-#define UARTDM_MISR_ADDR 0x10
-
-/* Read Only register */
-#define UARTDM_ISR_ADDR 0x14
-#define UARTDM_RX_TOTAL_SNAP_ADDR 0x38
-
 #define UARTDM_TXFS_ADDR 0x4C
 #define UARTDM_RXFS_ADDR 0x50
 
@@ -155,11 +137,25 @@
 #define RESET_TX_ERROR		0x800
 #define RESET_TX_DONE		0x810
 
+/*
+ * UARTDM_CR BAM IFC comman bit value
+ * for UARTDM Core v1.4
+ */
+#define START_RX_BAM_IFC	0x850
+#define START_TX_BAM_IFC	0x860
+
 #define UARTDM_MR1_AUTO_RFR_LEVEL1_BMSK 0xffffff00
 #define UARTDM_MR1_AUTO_RFR_LEVEL0_BMSK 0x3f
 #define UARTDM_MR1_CTS_CTL_BMSK 0x40
 #define UARTDM_MR1_RX_RDY_CTL_BMSK 0x80
 
+/*
+ * UARTDM Core v1.4 MR2_RFR_CTS_LOOP bitmask
+ * Enables internal loopback between RFR_N of
+ * RX channel and CTS_N of TX channel.
+ */
+#define UARTDM_MR2_RFR_CTS_LOOP_MODE_BMSK	0x400
+
 #define UARTDM_MR2_LOOP_MODE_BMSK		0x80
 #define UARTDM_MR2_ERROR_MODE_BMSK		0x40
 #define UARTDM_MR2_BITS_PER_CHAR_BMSK		0x30
@@ -204,4 +200,110 @@
 #define UARTDM_TX_DM_EN_BMSK 0x1
 #define UARTDM_RX_DM_EN_BMSK 0x2
 
+/*
+ * UARTDM Core v1.4 bitmask
+ * Bitmasks for enabling Rx and Tx BAM Interface
+ */
+#define UARTDM_TX_BAM_ENABLE_BMSK 0x4
+#define UARTDM_RX_BAM_ENABLE_BMSK 0x8
+
+/*
+ * Some of the BLSP Based UART Core(v14) existing register offsets
+ * are different compare to GSBI based UART Core(v13)
+ * Hence add the changed register offsets for UART Core v14
+ */
+#ifdef CONFIG_MSM_UARTDM_Core_v14
+
+/* write only register */
+#define UARTDM_CSR_ADDR    0x0a
+
+/* write only register */
+#define UARTDM_TF_ADDR   0x100
+#define UARTDM_TF2_ADDR  0x104
+#define UARTDM_TF3_ADDR  0x108
+#define UARTDM_TF4_ADDR  0x10c
+#define UARTDM_TF5_ADDR  0x110
+#define UARTDM_TF6_ADDR  0x114
+#define UARTDM_TF7_ADDR  0x118
+#define UARTDM_TF8_ADDR  0x11c
+#define UARTDM_TF9_ADDR  0x120
+#define UARTDM_TF10_ADDR 0x124
+#define UARTDM_TF11_ADDR 0x128
+#define UARTDM_TF12_ADDR 0x12c
+#define UARTDM_TF13_ADDR 0x130
+#define UARTDM_TF14_ADDR 0x134
+#define UARTDM_TF15_ADDR 0x138
+#define UARTDM_TF16_ADDR 0x13c
+
+/* write only register */
+#define UARTDM_CR_ADDR 0xa8
+/* write only register */
+#define UARTDM_IMR_ADDR 0xb0
+#define UARTDM_IRDA_ADDR 0xb8
+
+/* Read Only register */
+#define UARTDM_SR_ADDR 0xa4
+
+/* Read Only register */
+#define UARTDM_RF_ADDR   0x140
+#define UARTDM_RF2_ADDR  0x144
+#define UARTDM_RF3_ADDR  0x148
+#define UARTDM_RF4_ADDR  0x14c
+#define UARTDM_RF5_ADDR  0x150
+#define UARTDM_RF6_ADDR  0x154
+#define UARTDM_RF7_ADDR  0x158
+#define UARTDM_RF8_ADDR  0x15c
+#define UARTDM_RF9_ADDR  0x160
+#define UARTDM_RF10_ADDR 0x164
+#define UARTDM_RF11_ADDR 0x168
+#define UARTDM_RF12_ADDR 0x16c
+#define UARTDM_RF13_ADDR 0x170
+#define UARTDM_RF14_ADDR 0x174
+#define UARTDM_RF15_ADDR 0x178
+#define UARTDM_RF16_ADDR 0x17c
+
+/* Read Only register */
+#define UARTDM_MISR_ADDR 0xac
+
+/* Read Only register */
+#define UARTDM_ISR_ADDR 0xb4
+#define UARTDM_RX_TOTAL_SNAP_ADDR 0xbc
+
+#else
+
+/* Register offsets for UART Core v13 */
+
+/* write only register */
+#define UARTDM_CSR_ADDR    0x8
+
+/* write only register */
+#define UARTDM_TF_ADDR   0x70
+#define UARTDM_TF2_ADDR  0x74
+#define UARTDM_TF3_ADDR  0x78
+#define UARTDM_TF4_ADDR  0x7c
+
+/* write only register */
+#define UARTDM_CR_ADDR 0x10
+/* write only register */
+#define UARTDM_IMR_ADDR 0x14
+#define UARTDM_IRDA_ADDR 0x38
+
+/* Read Only register */
+#define UARTDM_SR_ADDR 0x8
+
+/* Read Only register */
+#define UARTDM_RF_ADDR   0x70
+#define UARTDM_RF2_ADDR  0x74
+#define UARTDM_RF3_ADDR  0x78
+#define UARTDM_RF4_ADDR  0x7c
+
+/* Read Only register */
+#define UARTDM_MISR_ADDR 0x10
+
+/* Read Only register */
+#define UARTDM_ISR_ADDR 0x14
+#define UARTDM_RX_TOTAL_SNAP_ADDR 0x38
+
+#endif
+
 #endif /* MSM_SERIAL_HS_HWREG_H */
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index ccb9aa3..1ee0828 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -189,6 +189,7 @@
 	u32			bus_perf_client;
 	struct msm_bus_scale_pdata	*bus_scale_table;
 	struct power_supply	usb_psy;
+	struct power_supply	*ext_vbus_psy;
 	unsigned int		online;
 	unsigned int		host_mode;
 	unsigned int		current_max;
@@ -197,6 +198,7 @@
 	unsigned int		vdd_high_vol_level;
 	bool			vbus_active;
 	bool			ext_inuse;
+	enum dwc3_id_state	id_state;
 };
 
 #define USB_HSPHY_3P3_VOL_MIN		3050000 /* uV */
@@ -1441,6 +1443,7 @@
 	struct dwc3_msm *mdwc = context;
 
 	if (start == false) {
+		dev_dbg(mdwc->dev, "canceling charging detection work\n");
 		cancel_delayed_work_sync(&mdwc->chg_work);
 		mdwc->chg_state = USB_CHG_STATE_UNDEFINED;
 		charger->chg_type = DWC3_INVALID_CHARGER;
@@ -1797,8 +1800,8 @@
 	/* Process PMIC notification in PRESENT prop */
 	case POWER_SUPPLY_PROP_PRESENT:
 		dev_dbg(mdwc->dev, "%s: notify xceiv event\n", __func__);
-		if (mdwc->otg_xceiv && (mdwc->ext_xceiv.otg_capability ||
-							!init)) {
+		if (mdwc->otg_xceiv && !mdwc->ext_inuse &&
+		    (mdwc->ext_xceiv.otg_capability || !init)) {
 			mdwc->ext_xceiv.bsv = val->intval;
 			if (atomic_read(&mdwc->in_lpm)) {
 				dev_dbg(mdwc->dev,
@@ -1810,9 +1813,10 @@
 							mdwc->otg_xceiv->otg,
 							DWC3_EVENT_XCEIV_STATE);
 			}
+
+			if (!init)
+				init = true;
 		}
-		if (!init)
-			init = true;
 		mdwc->vbus_active = val->intval;
 		break;
 	case POWER_SUPPLY_PROP_ONLINE:
@@ -1829,6 +1833,33 @@
 	return 0;
 }
 
+static void dwc3_msm_external_power_changed(struct power_supply *psy)
+{
+	struct dwc3_msm *mdwc = container_of(psy, struct dwc3_msm, usb_psy);
+	union power_supply_propval ret = {0,};
+
+	if (!mdwc->ext_vbus_psy)
+		mdwc->ext_vbus_psy = power_supply_get_by_name("ext-vbus");
+
+	if (!mdwc->ext_vbus_psy) {
+		pr_err("%s: Unable to get ext_vbus power_supply\n", __func__);
+		return;
+	}
+
+	mdwc->ext_vbus_psy->get_property(mdwc->ext_vbus_psy,
+					POWER_SUPPLY_PROP_ONLINE, &ret);
+	if (ret.intval) {
+		dwc3_start_chg_det(&mdwc->charger, false);
+		mdwc->ext_vbus_psy->get_property(mdwc->ext_vbus_psy,
+					POWER_SUPPLY_PROP_CURRENT_MAX, &ret);
+		power_supply_set_current_limit(&mdwc->usb_psy, ret.intval);
+	}
+
+	power_supply_set_online(&mdwc->usb_psy, ret.intval);
+	power_supply_changed(&mdwc->usb_psy);
+}
+
+
 static char *dwc3_msm_pm_power_supplied_to[] = {
 	"battery",
 };
@@ -1845,6 +1876,7 @@
 static void dwc3_ext_notify_online(int on)
 {
 	struct dwc3_msm *mdwc = context;
+	bool notify_otg = false;
 
 	if (!mdwc) {
 		pr_err("%s: DWC3 driver already removed\n", __func__);
@@ -1853,11 +1885,31 @@
 
 	dev_dbg(mdwc->dev, "notify %s%s\n", on ? "" : "dis", "connected");
 
-	if (!on) {
-		/* external client offline; revert back to USB */
-		mdwc->ext_inuse = false;
-		queue_delayed_work(system_nrt_wq, &mdwc->resume_work, 0);
+	if (!mdwc->ext_vbus_psy)
+		mdwc->ext_vbus_psy = power_supply_get_by_name("ext-vbus");
+
+	mdwc->ext_inuse = on;
+	if (on) {
+		/* force OTG to exit B-peripheral state */
+		mdwc->ext_xceiv.bsv = false;
+		notify_otg = true;
+		dwc3_start_chg_det(&mdwc->charger, false);
+	} else {
+		/* external client offline; tell OTG about cached ID/BSV */
+		if (mdwc->ext_xceiv.id != mdwc->id_state) {
+			mdwc->ext_xceiv.id = mdwc->id_state;
+			notify_otg = true;
+		}
+
+		mdwc->ext_xceiv.bsv = mdwc->vbus_active;
+		notify_otg |= mdwc->vbus_active;
 	}
+
+	if (mdwc->ext_vbus_psy)
+		power_supply_set_present(mdwc->ext_vbus_psy, on);
+
+	if (notify_otg)
+		queue_delayed_work(system_nrt_wq, &mdwc->resume_work, 0);
 }
 
 static bool dwc3_ext_trigger_handled(struct dwc3_msm *mdwc,
@@ -1887,21 +1939,26 @@
 	dev_dbg(mdwc->dev, "%s: state = %s\n", __func__,
 			state == ADC_TM_HIGH_STATE ? "high" : "low");
 
+	/* Give external client a chance to handle */
+	if (!mdwc->ext_inuse)
+		dwc3_ext_trigger_handled(mdwc, (state == ADC_TM_HIGH_STATE));
+
+	/* save ID state, but don't necessarily notify OTG */
 	if (state == ADC_TM_HIGH_STATE) {
-		mdwc->ext_xceiv.id = DWC3_ID_FLOAT;
+		mdwc->id_state = DWC3_ID_FLOAT;
 		mdwc->adc_param.state_request = ADC_TM_LOW_THR_ENABLE;
 	} else {
-		mdwc->ext_xceiv.id = DWC3_ID_GROUND;
+		mdwc->id_state = DWC3_ID_GROUND;
 		mdwc->adc_param.state_request = ADC_TM_HIGH_THR_ENABLE;
 	}
 
-	/* Give external client a chance to handle, otherwise notify OTG */
-	if (!mdwc->ext_inuse &&
-			!dwc3_ext_trigger_handled(mdwc, mdwc->ext_xceiv.id))
-		queue_delayed_work(system_nrt_wq, &mdwc->resume_work, 0);
-
 	/* re-arm ADC interrupt */
 	qpnp_adc_tm_usbid_configure(&mdwc->adc_param);
+
+	if (!mdwc->ext_inuse) { /* notify OTG */
+		mdwc->ext_xceiv.id = mdwc->id_state;
+		queue_delayed_work(system_nrt_wq, &mdwc->resume_work, 0);
+	}
 }
 
 static void dwc3_init_adc_work(struct work_struct *w)
@@ -2234,6 +2291,8 @@
 	msm->usb_psy.num_properties = ARRAY_SIZE(dwc3_msm_pm_power_props_usb);
 	msm->usb_psy.get_property = dwc3_msm_power_get_property_usb;
 	msm->usb_psy.set_property = dwc3_msm_power_set_property_usb;
+	msm->usb_psy.external_power_changed =
+				dwc3_msm_external_power_changed;
 
 	ret = power_supply_register(&pdev->dev, &msm->usb_psy);
 	if (ret < 0) {
diff --git a/drivers/usb/gadget/f_diag.c b/drivers/usb/gadget/f_diag.c
index aca2af3..a95bf24 100644
--- a/drivers/usb/gadget/f_diag.c
+++ b/drivers/usb/gadget/f_diag.c
@@ -2,7 +2,7 @@
  * Diag Function Device - Route ARM9 and ARM11 DIAG messages
  * between HOST and DEVICE.
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2013, Linux Foundation. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -334,22 +334,10 @@
 }
 EXPORT_SYMBOL(usb_diag_close);
 
-/**
- * usb_diag_free_req() - Free USB requests
- * @ch: Channel handler
- *
- * This function free read and write USB requests for the interface
- * associated with this channel.
- *
- */
-void usb_diag_free_req(struct usb_diag_ch *ch)
+static void free_reqs(struct diag_context *ctxt)
 {
-	struct diag_context *ctxt = ch->priv_usb;
-	struct usb_request *req;
 	struct list_head *act, *tmp;
-
-	if (!ctxt)
-		return;
+	struct usb_request *req;
 
 	list_for_each_safe(act, tmp, &ctxt->write_pool) {
 		req = list_entry(act, struct usb_request, list);
@@ -363,6 +351,27 @@
 		usb_ep_free_request(ctxt->out, req);
 	}
 }
+
+/**
+ * usb_diag_free_req() - Free USB requests
+ * @ch: Channel handler
+ *
+ * This function free read and write USB requests for the interface
+ * associated with this channel.
+ *
+ */
+void usb_diag_free_req(struct usb_diag_ch *ch)
+{
+	struct diag_context *ctxt = ch->priv_usb;
+	unsigned long flags;
+
+	if (ctxt) {
+		spin_lock_irqsave(&ctxt->lock, flags);
+		free_reqs(ctxt);
+		spin_unlock_irqrestore(&ctxt->lock, flags);
+	}
+
+}
 EXPORT_SYMBOL(usb_diag_free_req);
 
 /**
@@ -381,10 +390,14 @@
 	struct diag_context *ctxt = ch->priv_usb;
 	struct usb_request *req;
 	int i;
+	unsigned long flags;
 
 	if (!ctxt)
 		return -ENODEV;
 
+	spin_lock_irqsave(&ctxt->lock, flags);
+	/* Free previous session's stale requests */
+	free_reqs(ctxt);
 	for (i = 0; i < n_write; i++) {
 		req = usb_ep_alloc_request(ctxt->in, GFP_ATOMIC);
 		if (!req)
@@ -400,11 +413,11 @@
 		req->complete = diag_read_complete;
 		list_add_tail(&req->list, &ctxt->read_pool);
 	}
-
+	spin_unlock_irqrestore(&ctxt->lock, flags);
 	return 0;
-
 fail:
-	usb_diag_free_req(ch);
+	free_reqs(ctxt);
+	spin_unlock_irqrestore(&ctxt->lock, flags);
 	return -ENOMEM;
 
 }
diff --git a/drivers/usb/gadget/u_bam.c b/drivers/usb/gadget/u_bam.c
index 4947f15..00744fb 100644
--- a/drivers/usb/gadget/u_bam.c
+++ b/drivers/usb/gadget/u_bam.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, 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
@@ -220,7 +220,7 @@
 		ret = usb_ep_queue(ep, req, GFP_ATOMIC);
 		spin_lock(&port->port_lock_dl);
 		if (ret) {
-			pr_err("%s: usb epIn failed\n", __func__);
+			pr_err("%s: usb epIn failed with %d\n", __func__, ret);
 			list_add(&req->list, &d->tx_idle);
 			dev_kfree_skb_any(skb);
 			break;
@@ -517,7 +517,8 @@
 			dev_kfree_skb_any(skb);
 
 			if (printk_ratelimit())
-				pr_err("%s: rx queue failed\n", __func__);
+				pr_err("%s: rx queue failed %d\n",
+							__func__, ret);
 
 			if (port->port_usb)
 				list_add(&req->list, &d->rx_idle);
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 3ad05b06..a4bb7b2 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2013, 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
@@ -2167,8 +2167,8 @@
 	}
 }
 
-#define MSM_CHG_DCD_POLL_TIME		(100 * HZ/1000) /* 100 msec */
-#define MSM_CHG_DCD_MAX_RETRIES		6 /* Tdcd_tmout = 6 * 100 msec */
+#define MSM_CHG_DCD_TIMEOUT		(750 * HZ/1000) /* 750 msec */
+#define MSM_CHG_DCD_POLL_TIME		(50 * HZ/1000) /* 50 msec */
 #define MSM_CHG_PRIMARY_DET_TIME	(50 * HZ/1000) /* TVDPSRC_ON */
 #define MSM_CHG_SECONDARY_DET_TIME	(50 * HZ/1000) /* TVDMSRC_ON */
 static void msm_chg_detect_work(struct work_struct *w)
@@ -2192,7 +2192,7 @@
 		msm_chg_enable_dcd(motg);
 		msm_chg_enable_aca_det(motg);
 		motg->chg_state = USB_CHG_STATE_WAIT_FOR_DCD;
-		motg->dcd_retries = 0;
+		motg->dcd_time = 0;
 		delay = MSM_CHG_DCD_POLL_TIME;
 		break;
 	case USB_CHG_STATE_WAIT_FOR_DCD:
@@ -2217,7 +2217,8 @@
 			}
 		}
 		is_dcd = msm_chg_check_dcd(motg);
-		tmout = ++motg->dcd_retries == MSM_CHG_DCD_MAX_RETRIES;
+		motg->dcd_time += MSM_CHG_DCD_POLL_TIME;
+		tmout = motg->dcd_time >= MSM_CHG_DCD_TIMEOUT;
 		if (is_dcd || tmout) {
 			msm_chg_disable_dcd(motg);
 			msm_chg_enable_primary_det(motg);
diff --git a/drivers/video/msm/mdss/mhl_sii8334.c b/drivers/video/msm/mdss/mhl_sii8334.c
index 0227e70..f3be983 100644
--- a/drivers/video/msm/mdss/mhl_sii8334.c
+++ b/drivers/video/msm/mdss/mhl_sii8334.c
@@ -30,6 +30,7 @@
 
 #define MHL_DRIVER_NAME "sii8334"
 #define COMPATIBLE_NAME "qcom,mhl-sii8334"
+#define MAX_CURRENT 700000
 
 #define pr_debug_intr(...) pr_debug("\n")
 
@@ -63,6 +64,9 @@
 	void (*notify_usb_online)(int online);
 	struct usb_ext_notification *mhl_info;
 	bool disc_enabled;
+	struct power_supply mhl_psy;
+	bool vbus_active;
+	int current_val;
 };
 
 
@@ -267,6 +271,65 @@
 	return rc;
 }
 
+static int mhl_power_get_property(struct power_supply *psy,
+				  enum power_supply_property psp,
+				  union power_supply_propval *val)
+{
+	struct mhl_tx_ctrl *mhl_ctrl =
+		container_of(psy, struct mhl_tx_ctrl, mhl_psy);
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_CURRENT_MAX:
+		val->intval = mhl_ctrl->current_val;
+		break;
+	case POWER_SUPPLY_PROP_PRESENT:
+		val->intval = mhl_ctrl->vbus_active;
+		break;
+	case POWER_SUPPLY_PROP_ONLINE:
+		val->intval = mhl_ctrl->vbus_active && mhl_ctrl->mhl_mode;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int mhl_power_set_property(struct power_supply *psy,
+				  enum power_supply_property psp,
+				  const union power_supply_propval *val)
+{
+	struct mhl_tx_ctrl *mhl_ctrl =
+		container_of(psy, struct mhl_tx_ctrl, mhl_psy);
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_PRESENT:
+		mhl_ctrl->vbus_active = val->intval;
+		if (mhl_ctrl->vbus_active)
+			mhl_ctrl->current_val = MAX_CURRENT;
+		else
+			mhl_ctrl->current_val = 0;
+		power_supply_changed(psy);
+		break;
+	case POWER_SUPPLY_PROP_ONLINE:
+	case POWER_SUPPLY_PROP_CURRENT_MAX:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static char *mhl_pm_power_supplied_to[] = {
+	"usb",
+};
+
+static enum power_supply_property mhl_pm_power_props[] = {
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_ONLINE,
+	POWER_SUPPLY_PROP_CURRENT_MAX,
+};
+
 static void cbus_reset(struct i2c_client *client)
 {
 	uint8_t i;
@@ -620,6 +683,7 @@
 	if (0x02 == rgnd_imp) {
 		pr_debug("%s: mhl sink\n", __func__);
 		mhl_ctrl->mhl_mode = 1;
+		power_supply_changed(&mhl_ctrl->mhl_psy);
 		if (mhl_ctrl->notify_usb_online)
 			mhl_ctrl->notify_usb_online(1);
 	} else {
@@ -718,9 +782,9 @@
 		/* Short RGND */
 		MHL_SII_REG_NAME_MOD(REG_DISC_STAT2, BIT0 | BIT1, 0x00);
 		mhl_msm_disconnection(mhl_ctrl);
+		power_supply_changed(&mhl_ctrl->mhl_psy);
 		if (mhl_ctrl->notify_usb_online)
 			mhl_ctrl->notify_usb_online(0);
-
 	}
 
 	if (status & BIT5) {
@@ -730,6 +794,7 @@
 		reg = MHL_SII_REG_NAME_RD(REG_INTR4);
 		MHL_SII_REG_NAME_WR(REG_INTR4, reg);
 		mhl_msm_disconnection(mhl_ctrl);
+		power_supply_changed(&mhl_ctrl->mhl_psy);
 		if (mhl_ctrl->notify_usb_online)
 			mhl_ctrl->notify_usb_online(0);
 	}
@@ -1255,6 +1320,24 @@
 	} else {
 		pr_debug("request_threaded_irq succeeded\n");
 	}
+
+	mhl_ctrl->mhl_psy.name = "ext-vbus";
+	mhl_ctrl->mhl_psy.type = POWER_SUPPLY_TYPE_USB_DCP;
+	mhl_ctrl->mhl_psy.supplied_to = mhl_pm_power_supplied_to;
+	mhl_ctrl->mhl_psy.num_supplicants = ARRAY_SIZE(
+					mhl_pm_power_supplied_to);
+	mhl_ctrl->mhl_psy.properties = mhl_pm_power_props;
+	mhl_ctrl->mhl_psy.num_properties = ARRAY_SIZE(mhl_pm_power_props);
+	mhl_ctrl->mhl_psy.get_property = mhl_power_get_property;
+	mhl_ctrl->mhl_psy.set_property = mhl_power_set_property;
+
+	rc = power_supply_register(&client->dev, &mhl_ctrl->mhl_psy);
+	if (rc < 0) {
+		dev_err(&client->dev, "%s:power_supply_register ext_vbus_psy failed\n",
+			__func__);
+		goto failed_probe;
+	}
+
 	pr_debug("%s: i2c client addr is [%x]\n", __func__, client->addr);
 
 	mhl_info = devm_kzalloc(&client->dev, sizeof(*mhl_info), GFP_KERNEL);
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
index 95f4bf0..5cf2f9c 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -1115,14 +1115,21 @@
 				encoder->client_output_buf_req.sz/num_slices;
 				encoder->client_output_buf_req.sz =
 				DDL_ALIGN(output_buf_size, DDL_KILO_BYTE(4));
+				if (encoder->client_output_buf_req. \
+					actual_count < encoder-> \
+					client_output_buf_req.min_count) {
+					encoder->client_output_buf_req. \
+					actual_count = encoder-> \
+					client_output_buf_req.min_count;
+				}
 				encoder->output_buf_req =
 				encoder->client_output_buf_req;
-				DDL_MSG_HIGH("%s num_mb = %u num_slices = %u "
-				"output_buf_count = %u "
-				"output_buf_size = %u aligned size = %u\n",
+				DDL_MSG_HIGH("%s num_mb = %u num_slices = %u" \
+				" min_count = %u act_count = %u" \
+				" aligned size = %u\n",
 				__func__, num_mb, num_slices,
 				encoder->client_output_buf_req.min_count,
-				output_buf_size,
+				encoder->client_output_buf_req.actual_count,
 				encoder->client_output_buf_req.sz);
 				vcd_status = VCD_S_SUCCESS;
 			}
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c
index 983923b..884050b 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_client_sm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -1750,7 +1750,7 @@
 	 vcd_get_buffer_requirements_cmn,
 	 NULL,
 	 NULL,
-	 NULL,
+	 vcd_free_buffer_cmn,
 	 vcd_fill_output_buffer_cmn,
 	 vcd_clnt_cb_in_flushing,
 	 },
diff --git a/include/linux/mfd/pm8xxx/pm8921-bms.h b/include/linux/mfd/pm8xxx/pm8921-bms.h
index 6db6204..8ab3ac2 100644
--- a/include/linux/mfd/pm8xxx/pm8921-bms.h
+++ b/include/linux/mfd/pm8xxx/pm8921-bms.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2013, Code Aurora Forum. 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
@@ -123,9 +123,11 @@
 int pm8921_bms_get_simultaneous_battery_voltage_and_current(int *ibat_ua,
 								int *vbat_uv);
 /**
- * pm8921_bms_get_rbatt - function to get the battery resistance in mOhm.
+ * pm8921_bms_get_current_max
+ *	- function to get the max current that can be drawn from
+ *	  the battery before it dips below the min allowed voltage
  */
-int pm8921_bms_get_rbatt(void);
+int pm8921_bms_get_current_max(void);
 /**
  * pm8921_bms_invalidate_shutdown_soc - function to notify the bms driver that
  *					the battery was replaced between reboot
@@ -184,6 +186,10 @@
 {
 	return -ENXIO;
 }
+static inline int pm8921_bms_get_current_max(void)
+{
+	return -ENXIO;
+}
 #endif
 
 #endif
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 3e5c8cb..4d004c2 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -198,6 +198,7 @@
 	REL_WRITE,
 	THRESHOLD,
 	LARGE_SEC_ALIGN,
+	RANDOM,
 	MAX_REASONS,
 };
 
@@ -261,32 +262,48 @@
 /**
  * struct mmc_bkops_info - BKOPS data
  * @dw:	Idle time bkops delayed work
- * @host_suspend_tout_ms:	The host controller idle time,
- * before getting into suspend
+ * @host_delay_ms:	The host controller time to start bkops
  * @delay_ms:	The time to start the BKOPS
  *        delayed work once MMC thread is idle
+ * @min_sectors_to_queue_delayed_work: the changed
+ *        number of sectors that should issue check for BKOPS
+ *        need
+ * @size_percentage_to_queue_delayed_work: the changed
+ *        percentage of sectors that should issue check for
+ *        BKOPS need
+ * @bkops_stats: BKOPS statistics
  * @poll_for_completion:	Poll on BKOPS completion
  * @cancel_delayed_work: A flag to indicate if the delayed work
  *        should be cancelled
- * @started_delayed_bkops:  A flag to indicate if the delayed
- *        work was scheduled
+ * @sectors_changed:  number of  sectors written or
+ *       discard since the last idle BKOPS were scheduled
  */
 struct mmc_bkops_info {
 	struct delayed_work	dw;
-	unsigned int		host_suspend_tout_ms;
+	unsigned int		host_delay_ms;
 	unsigned int		delay_ms;
-	struct mmc_bkops_stats  bkops_stats;    /* BKOPS statistics */
+	unsigned int		min_sectors_to_queue_delayed_work;
+	unsigned int		size_percentage_to_queue_delayed_work;
+	struct mmc_bkops_stats  bkops_stats;
 /*
  * A default time for checking the need for non urgent BKOPS once mmcqd
  * is idle.
  */
-#define MMC_IDLE_BKOPS_TIME_MS 2000
+#define MMC_IDLE_BKOPS_TIME_MS 200
 	struct work_struct	poll_for_completion;
 /* Polling timeout and interval for waiting on non-blocking BKOPs completion */
-#define BKOPS_COMPLETION_POLLING_TIMEOUT_MS 10000 /* in ms */
+#define BKOPS_COMPLETION_POLLING_TIMEOUT_MS (4 * 60 * 1000) /* in ms */
 #define BKOPS_COMPLETION_POLLING_INTERVAL_MS 1000 /* in ms */
 	bool			cancel_delayed_work;
-	bool			started_delayed_bkops;
+	unsigned int		sectors_changed;
+/*
+ * Since canceling the delayed work might have significant effect on the
+ * performance of small requests we won't queue the delayed work every time
+ * mmcqd thread is idle.
+ * The delayed work for idle BKOPS will be scheduled only after a significant
+ * amount of write or discard data.
+ */
+#define BKOPS_SIZE_PERCENTAGE_TO_QUEUE_DELAYED_WORK 1 /* 1% */
 };
 
 /**
@@ -337,6 +354,7 @@
 #define MMC_CARD_REMOVED	(1<<7)		/* card has been removed */
 #define MMC_STATE_HIGHSPEED_200	(1<<8)		/* card is in HS200 mode */
 #define MMC_STATE_DOING_BKOPS	(1<<10)		/* card is doing BKOPS */
+#define MMC_STATE_NEED_BKOPS	(1<<11)		/* card needs to do BKOPS */
 	unsigned int		quirks; 	/* card quirks */
 #define MMC_QUIRK_LENIENT_FN0	(1<<0)		/* allow SDIO FN0 writes outside of the VS CCCR range */
 #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1)	/* use func->cur_blksize */
@@ -511,6 +529,7 @@
 #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
 #define mmc_card_removed(c)	((c) && ((c)->state & MMC_CARD_REMOVED))
 #define mmc_card_doing_bkops(c)	((c)->state & MMC_STATE_DOING_BKOPS)
+#define mmc_card_need_bkops(c)	((c)->state & MMC_STATE_NEED_BKOPS)
 
 #define mmc_card_set_present(c)	((c)->state |= MMC_STATE_PRESENT)
 #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
@@ -524,7 +543,8 @@
 #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED)
 #define mmc_card_set_doing_bkops(c)	((c)->state |= MMC_STATE_DOING_BKOPS)
 #define mmc_card_clr_doing_bkops(c)	((c)->state &= ~MMC_STATE_DOING_BKOPS)
-
+#define mmc_card_set_need_bkops(c)	((c)->state |= MMC_STATE_NEED_BKOPS)
+#define mmc_card_clr_need_bkops(c)	((c)->state &= ~MMC_STATE_NEED_BKOPS)
 /*
  * Quirk add/remove for MMC products.
  */
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 6982c45..f9e0627 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -315,6 +315,7 @@
 
 	struct delayed_work	detect;
 	struct wake_lock	detect_wake_lock;
+	const char		*wlock_name;
 	int			detect_change;	/* card detect flag */
 	struct mmc_hotplug	hotplug;
 
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 279b72f..9240277 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Author: Brian Swetland <swetland@google.com>
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-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
@@ -340,7 +340,7 @@
 	struct delayed_work suspend_work;
 	enum usb_chg_state chg_state;
 	enum usb_chg_type chg_type;
-	u8 dcd_retries;
+	unsigned dcd_time;
 	struct wake_lock wlock;
 	struct notifier_block usbdev_nb;
 	unsigned mA_port;
@@ -456,6 +456,13 @@
 	u32 desc_fifo_size;
 };
 
+enum usb_bam {
+	SSUSB_BAM = 0,
+	HSUSB_BAM,
+	HSIC_BAM,
+	MAX_BAMS,
+};
+
 /**
  * struct msm_usb_bam_platform_data: pipe connection information
  * between USB/HSIC BAM and another BAM. USB/HSIC BAM can be
@@ -474,13 +481,7 @@
 	u32 total_bam_num;
 	u32 usb_base_address;
 	bool ignore_core_reset_ack;
-};
-
-enum usb_bam {
-	SSUSB_BAM = 0,
-	HSUSB_BAM,
-	HSIC_BAM,
-	MAX_BAMS,
+	bool reset_on_connect[MAX_BAMS];
 };
 
 /**
diff --git a/include/sound/q6afe-v2.h b/include/sound/q6afe-v2.h
index 444b432..3da152c 100644
--- a/include/sound/q6afe-v2.h
+++ b/include/sound/q6afe-v2.h
@@ -73,6 +73,8 @@
 	IDX_RT_PROXY_PORT_001_TX = 31,
 	IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX = 32,
 	IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX = 33,
+	IDX_AFE_PORT_ID_SECONDARY_MI2S_RX = 34,
+	IDX_AFE_PORT_ID_SECONDARY_MI2S_TX = 35,
 	AFE_MAX_PORTS
 };
 
diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c
index 1967297..f2aa5de 100644
--- a/lib/spinlock_debug.c
+++ b/lib/spinlock_debug.c
@@ -106,24 +106,28 @@
 static void __spin_lock_debug(raw_spinlock_t *lock)
 {
 	u64 i;
-	u64 loops = loops_per_jiffy * HZ;
-	int print_once = 1;
+	u64 loops = (loops_per_jiffy * HZ) >> 4;
 
-	for (;;) {
-		for (i = 0; i < loops; i++) {
-			if (arch_spin_trylock(&lock->raw_lock))
-				return;
-			__delay(1);
-		}
-		/* lockup suspected: */
-		if (print_once) {
-			print_once = 0;
-			spin_dump(lock, "lockup");
-#ifdef CONFIG_SMP
-			trigger_all_cpu_backtrace();
-#endif
-		}
+	for (i = 0; i < loops; i++) {
+		if (arch_spin_trylock(&lock->raw_lock))
+			return;
+		__delay(1);
 	}
+	/* lockup suspected: */
+	spin_dump(lock, "lockup");
+#ifdef CONFIG_SMP
+	trigger_all_cpu_backtrace();
+#endif
+
+	/*
+	 * The trylock above was causing a livelock.  Give the lower level arch
+	 * specific lock code a chance to acquire the lock. We have already
+	 * printed a warning/backtrace at this point. The non-debug arch
+	 * specific code might actually succeed in acquiring the lock.  If it is
+	 * not successful, the end-result is the same - there is no forward
+	 * progress.
+	 */
+	arch_spin_lock(&lock->raw_lock);
 }
 
 void do_raw_spin_lock(raw_spinlock_t *lock)
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index 73a39d5..1546b9e 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -198,6 +198,8 @@
 static const u32 vport_i2s_check_table[NUM_CODEC_DAIS] = {
 	0,	/* AIF1_PB */
 	0,	/* AIF1_CAP */
+	0,	/* AIF2_PB */
+	0,	/* AIF2_CAP */
 };
 
 struct taiko_priv {
@@ -1694,7 +1696,7 @@
 	mutex_lock(&codec->mutex);
 
 	if (taiko_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
-		if (widget->value > 1) {
+		if (widget->value > 2) {
 			dev_err(codec->dev, "%s: invalid AIF for I2C mode\n",
 				__func__);
 			goto err;
@@ -3743,6 +3745,34 @@
 		},
 		.ops = &taiko_dai_ops,
 	},
+	{
+		.name = "taiko_i2s_rx2",
+		.id = AIF1_PB,
+		.playback = {
+			.stream_name = "AIF2 Playback",
+			.rates = WCD9320_RATES,
+			.formats = TAIKO_FORMATS,
+			.rate_max = 192000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 4,
+		},
+		.ops = &taiko_dai_ops,
+	},
+	{
+		.name = "taiko_i2s_tx2",
+		.id = AIF1_CAP,
+		.capture = {
+			.stream_name = "AIF2 Capture",
+			.rates = WCD9320_RATES,
+			.formats = TAIKO_FORMATS,
+			.rate_max = 192000,
+			.rate_min = 8000,
+			.channels_min = 1,
+			.channels_max = 4,
+		},
+		.ops = &taiko_dai_ops,
+	},
 };
 
 static int taiko_codec_enable_slim_chmask(struct wcd9xxx_codec_dai_data *dai,
diff --git a/sound/soc/msm/mdm9625.c b/sound/soc/msm/mdm9625.c
index 4c7b69d..eadb365 100644
--- a/sound/soc/msm/mdm9625.c
+++ b/sound/soc/msm/mdm9625.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
@@ -27,13 +27,6 @@
 #include <qdsp6v2/msm-pcm-routing-v2.h>
 #include "../codecs/wcd9320.h"
 
-/* MI2S GPIO SECTION */
-
-#define GPIO_MI2S_WS     12
-#define GPIO_MI2S_SCLK   15
-#define GPIO_MI2S_DOUT   14
-#define GPIO_MI2S_DIN    13
-#define GPIO_MI2S_MCLK   71
 
 /* Spk control */
 #define MDM9625_SPK_ON 1
@@ -45,59 +38,61 @@
 #define MDM_MCLK_CLK_12P288MHZ 12288000
 #define MDM_MCLK_CLK_9P6HZ 9600000
 #define MDM_IBIT_CLK_DIV_1P56MHZ 7
+#define MDM_MI2S_PRIM_INTF 0
+#define MDM_MI2S_SEC_INTF  1
+
 
 /* Machine driver Name*/
 #define MDM9625_MACHINE_DRV_NAME "mdm9625-asoc-taiko"
 
-struct mdm9625_machine_data {
-	u32 mclk_freq;
+/* I2S GPIO */
+struct msm_i2s_gpio {
+	unsigned gpio_no;
+	const char *gpio_name;
+};
+
+struct msm_i2s_ctrl {
+	struct msm_i2s_gpio *pin_data;
+	struct clk *cdc_bit_clk;
+	u32 cnt;
 };
 
 /* MI2S clock */
 struct mdm_mi2s_clk {
 	struct clk *cdc_cr_clk;
 	struct clk *cdc_osr_clk;
-	struct clk *cdc_bit_clk;
-	bool clk_enable;
+	u32 clk_usrs;
+};
+
+struct mdm9625_machine_data {
+	u32 mclk_freq;
+	struct msm_i2s_gpio *mclk_pin;
+	struct msm_i2s_ctrl *pri_ctrl;
 
 };
-static struct mdm_mi2s_clk prim_clk;
 
-/* I2S GPIO */
-struct request_gpio {
-	unsigned gpio_no;
-	char *gpio_name;
+#define GPIO_NAME_INDEX 0
+#define DT_PARSE_INDEX  1
+
+
+static char *mdm_i2s_gpio_name[][2] = {
+	 {"PRIM_MI2S_WS",   "prim-i2s-gpio-ws"},
+	 {"PRIM_MI2S_DIN",  "prim-i2s-gpio-din"},
+	 {"PRIM_MI2S_DOUT", "prim-i2s-gpio-dout"},
+	 {"PRIM_MI2S_SCLK", "prim-i2s-gpio-sclk"},
 };
+
+static char *mdm_mclk_gpio[][2] = {
+	 {"MI2S_MCLK",      "prim-i2s-gpio-mclk"},
+};
+
+static struct mdm_mi2s_clk clk_ctl;
 static struct mutex cdc_mclk_mutex;
 static int mdm9625_mi2s_rx_ch = 1;
 static int mdm9625_mi2s_tx_ch = 1;
 static int msm_spk_control;
 static atomic_t mi2s_ref_count;
 
-/* MI2S GPIO CONFIG */
-static struct request_gpio mi2s_gpio[] = {
-	{
-		.gpio_no = GPIO_MI2S_WS,
-		.gpio_name = "MI2S_WS",
-	},
-	{
-		.gpio_no = GPIO_MI2S_SCLK,
-		.gpio_name = "MI2S_SCLK",
-	},
-	{
-		.gpio_no = GPIO_MI2S_DOUT,
-		.gpio_name = "MI2S_DOUT",
-	},
-	{
-		.gpio_no = GPIO_MI2S_DIN,
-		.gpio_name = "MI2S_DIN",
-	},
-	{
-		.gpio_no = GPIO_MI2S_MCLK,
-		.gpio_name = "MI2S_MCLK",
-	},
-};
-
 static int mdm9625_enable_codec_ext_clk(struct snd_soc_codec *codec,
 					int enable, bool dapm);
 
@@ -120,53 +115,104 @@
 #define WCD9XXX_MBHC_DEF_BUTTONS 8
 #define WCD9XXX_MBHC_DEF_RLOADS 5
 
-
-static bool gpio_enable;
-
-static int mdm9625_set_mi2s_gpio(void)
+static int mdm9625_set_mi2s_gpio(struct snd_pcm_substream *substream, u32 intf)
 {
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_card *card = rtd->card;
+	struct mdm9625_machine_data *pdata = snd_soc_card_get_drvdata(card);
+	struct msm_i2s_ctrl *i2s_ctrl = NULL;
+	struct msm_i2s_gpio *pin_data = NULL;
 	int rtn = 0;
 	int i;
 	int j;
 
-	if (gpio_enable == false) {
-		for (i = 0; i < ARRAY_SIZE(mi2s_gpio); i++) {
-			rtn = gpio_request(mi2s_gpio[i].gpio_no,
-					   mi2s_gpio[i].gpio_name);
-			pr_debug("%s: gpio = %d, gpio name = %s\n"
-				 "rtn = %d\n", __func__,
-				 mi2s_gpio[i].gpio_no,
-				 mi2s_gpio[i].gpio_name,
-				 rtn);
-			if (rtn) {
-				pr_err("%s: Failed to request gpio %d\n",
-					__func__, mi2s_gpio[i].gpio_no);
-				/* Release all the GPIO on failure */
-				for (j = i; j >= 0; j--)
-					gpio_free(mi2s_gpio[j].gpio_no);
-				goto err;
-			}
+	if (pdata == NULL) {
+		pr_err("%s: pdata is NULL\n", __func__);
+		rtn = -EINVAL;
+		goto err;
+	}
+
+	if (intf == MDM_MI2S_PRIM_INTF)
+		i2s_ctrl = pdata->pri_ctrl;
+	else {
+		pr_err("%s: Wrong I2S Interface\n", __func__);
+		rtn = -EINVAL;
+		goto err;
+	}
+	if (i2s_ctrl == NULL || i2s_ctrl->pin_data == NULL) {
+		pr_err("%s: Intf ptr NULL\n", __func__);
+		rtn = -EINVAL;
+		goto err;
+	}
+	pin_data = i2s_ctrl->pin_data;
+	for (i = 0; i < i2s_ctrl->cnt; i++, pin_data++) {
+		rtn = gpio_request(pin_data->gpio_no,
+				   pin_data->gpio_name);
+		pr_debug("%s: gpio = %d, gpio name = %s\n"
+			 "rtn = %d\n", __func__,
+			 pin_data->gpio_no,
+			 pin_data->gpio_name,
+			 rtn);
+		if (rtn) {
+			pr_err("%s: Failed to request gpio %d\n",
+				__func__, pin_data->gpio_no);
+			/* Release all the GPIO on failure */
+			for (j = i; j >= 0; j--)
+				gpio_free(pin_data->gpio_no);
+			goto err;
 		}
-	gpio_enable = true;
 	}
 err:
 	return rtn;
+
 }
 
-static int mdm9625_mi2s_free_gpios(void)
+static int mdm9625_mi2s_free_gpios(struct snd_pcm_substream *substream,
+				   u32 intf)
 {
 	int i;
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_card *card = rtd->card;
+	struct mdm9625_machine_data *pdata = snd_soc_card_get_drvdata(card);
+	struct msm_i2s_ctrl *i2s_ctrl = NULL;
+	struct msm_i2s_gpio *pin_data = NULL;
+	int rtn = 0;
+
 	pr_debug("%s:", __func__);
-	for (i = 0; i < ARRAY_SIZE(mi2s_gpio); i++)
-		gpio_free(mi2s_gpio[i].gpio_no);
-	gpio_enable = false;
-	return 0;
+	if (pdata == NULL) {
+		pr_err("%s: pdata is NULL\n", __func__);
+		rtn = -EINVAL;
+		goto err;
+	}
+	if (intf == MDM_MI2S_PRIM_INTF)
+		i2s_ctrl = pdata->pri_ctrl;
+	else {
+		pr_debug("%s: Wrong Interface\n", __func__);
+		rtn = -EINVAL;
+		goto err;
+	}
+	if (i2s_ctrl == NULL || i2s_ctrl->pin_data == NULL) {
+		pr_err("%s: Intf ptr NULL\n", __func__);
+		rtn = -EINVAL;
+		goto err;
+	}
+	pin_data = i2s_ctrl->pin_data;
+	for (i = 0; i < i2s_ctrl->cnt; i++, pin_data++) {
+		gpio_free(pin_data->gpio_no);
+		pr_debug("%s: gpio = %d, gpio name = %s\n",
+			 __func__, pin_data->gpio_no,
+			 pin_data->gpio_name);
+	}
+err:
+	return rtn;
+
 }
 static int mdm9625_mi2s_clk_ctl(struct snd_soc_pcm_runtime *rtd, bool enable)
 {
-	struct mdm_mi2s_clk *clk = &prim_clk;
+	struct mdm_mi2s_clk *clk = &clk_ctl;
 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	struct snd_soc_card *card = rtd->card;
+	struct clk *bclk = NULL;
 	struct mdm9625_machine_data *pdata = snd_soc_card_get_drvdata(card);
 	int ret = 0;
 
@@ -174,78 +220,52 @@
 		pr_err("%s:platform data is null\n", __func__);
 		return -ENODEV;
 	}
+	bclk = pdata->pri_ctrl->cdc_bit_clk;
 
 	if (enable) {
-		if (clk->clk_enable == true) {
-			pr_info("%s:Device clock already enabled\n", __func__);
-			return 0;
+		if (clk->clk_usrs == 0) {
+			/* Set rate core and ibit clock */
+			clk_set_rate(clk->cdc_cr_clk, pdata->mclk_freq);
+			/* Enable clocks. core clock need not be enabled.
+			 * Enabling branch clocks indirectly enables
+			 * core clock.
+			 */
+			ret = clk_prepare_enable(clk->cdc_osr_clk);
+			if (ret != 0) {
+				pr_err("Fail to enable cdc_osr_clk\n");
+				goto exit_osrclk_err;
+			}
 		}
-		/* Set up core clock. */
-		clk->cdc_cr_clk = clk_get(cpu_dai->dev, "core_clk");
-		if (IS_ERR(clk->cdc_cr_clk)) {
-			pr_err("%s: Failed to Core clk %ld\n"
-			       "CPU dai name %s\n", __func__,
-			       PTR_ERR(clk->cdc_cr_clk),
-			       cpu_dai->dev->driver->name);
-			return -ENODEV ;
-		}
-		/* osr clock */
-		clk->cdc_osr_clk = clk_get(cpu_dai->dev, "osr_clk");
-		if (IS_ERR(clk->cdc_osr_clk)) {
-			pr_err("%s: Failed to request OSR %ld\n"
-			       "CPU dai name %s\n", __func__,
-			       PTR_ERR(clk->cdc_osr_clk),
-			       cpu_dai->dev->driver->name);
-			clk_put(clk->cdc_cr_clk);
-			return -ENODEV ;
-		}
+		clk->clk_usrs++;
 		/* ibit clock */
-		clk->cdc_bit_clk = clk_get(cpu_dai->dev, "ibit_clk");
-		if (IS_ERR(clk->cdc_bit_clk)) {
+		bclk = clk_get(cpu_dai->dev, "ibit_clk");
+		if (IS_ERR(bclk)) {
 			pr_err("%s: Failed to request Bit %ld\n"
 			       "CPU dai name %s\n", __func__,
-			       PTR_ERR(clk->cdc_bit_clk),
+			       PTR_ERR(bclk),
 			       cpu_dai->dev->driver->name);
-			clk_put(clk->cdc_cr_clk);
-			clk_put(clk->cdc_osr_clk);
 			return -ENODEV ;
 		}
-		/* Set rate core and ibit clock */
-		clk_set_rate(clk->cdc_cr_clk, pdata->mclk_freq);
-		clk_set_rate(clk->cdc_bit_clk, MDM_IBIT_CLK_DIV_1P56MHZ);
-
-		/* Enable clocks. core clock need not be enabled.
-		 * Enabling branch clocks indirectly enables
-		 * core clock.
-		 */
-		ret = clk_prepare_enable(clk->cdc_osr_clk);
-		if (ret != 0) {
-			pr_err("Fail to enable cdc_osr_clk\n");
-			goto exit_osrclk_err;
-		}
-		ret = clk_prepare_enable(clk->cdc_bit_clk);
+		clk_set_rate(bclk, MDM_IBIT_CLK_DIV_1P56MHZ);
+		ret = clk_prepare_enable(bclk);
 		if (ret != 0) {
 			pr_err("Fail to enable cdc_bit_clk\n");
 			goto exit_bclk_err;
 		}
-		clk->clk_enable = true;
 		return ret;
 	} else {
-		clk->clk_enable = false;
+		if (clk->clk_usrs > 0)
+			clk->clk_usrs--;
 		ret = 0;
 		goto exit_bclk_err;
 	}
 exit_bclk_err:
-	clk_disable_unprepare(clk->cdc_bit_clk);
-	clk_put(clk->cdc_bit_clk);
+	clk_disable_unprepare(bclk);
+	clk_put(bclk);
 exit_osrclk_err:
-	clk_disable_unprepare(clk->cdc_osr_clk);
-	clk_put(clk->cdc_osr_clk);
-	clk_put(clk->cdc_cr_clk);
-	clk->cdc_cr_clk = NULL;
-	clk->cdc_bit_clk = NULL;
-	clk->cdc_osr_clk = NULL;
-	clk->clk_enable = false;
+	if (clk->clk_usrs == 0)
+		clk_disable_unprepare(clk->cdc_osr_clk);
+	bclk = NULL;
 	return ret;
 }
 
@@ -254,7 +274,7 @@
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	int ret;
 	if (atomic_dec_return(&mi2s_ref_count) == 0) {
-		mdm9625_mi2s_free_gpios();
+		mdm9625_mi2s_free_gpios(substream, MDM_MI2S_PRIM_INTF);
 		ret = mdm9625_mi2s_clk_ctl(rtd, false);
 		if (ret < 0)
 			pr_err("%s:clock disable failed\n", __func__);
@@ -269,7 +289,7 @@
 	int ret = 0;
 
 	if (atomic_inc_return(&mi2s_ref_count) == 1) {
-		mdm9625_set_mi2s_gpio();
+		mdm9625_set_mi2s_gpio(substream, MDM_MI2S_PRIM_INTF);
 		ret = mdm9625_mi2s_clk_ctl(rtd, true);
 		if (ret < 0) {
 			pr_err("set format for codec dai failed\n");
@@ -397,13 +417,36 @@
 					int enable, bool dapm)
 {
 	int ret = 0;
+	struct mdm9625_machine_data *pdata =
+			snd_soc_card_get_drvdata(codec->card);
+	struct mdm_mi2s_clk *clk = &clk_ctl;
+
 	pr_debug("%s: enable = %d  codec name %s\n", __func__,
-		enable, codec->name);
+		 enable, codec->name);
 	mutex_lock(&cdc_mclk_mutex);
-	if (enable)
+
+	if (enable) {
+		if (clk->clk_usrs == 0) {
+			/* Set rate core and ibit clock */
+			clk_set_rate(clk->cdc_cr_clk, pdata->mclk_freq);
+			/* Enable clocks. core clock need not be enabled.
+			 * Enabling branch clocks indirectly enables
+			 * core clock.
+			 */
+			ret = clk_prepare_enable(clk->cdc_osr_clk);
+			if (ret != 0)
+				pr_err("Fail to enable cdc_osr_clk\n");
+		}
+		clk->clk_usrs++;
 		taiko_mclk_enable(codec, 1, dapm);
-	else
+
+	} else {
+		if (clk->clk_usrs > 0)
+			clk->clk_usrs--;
+		if (clk->clk_usrs == 0)
+			clk_disable_unprepare(clk->cdc_osr_clk);
 		taiko_mclk_enable(codec, 0, dapm);
+	}
 	mutex_unlock(&cdc_mclk_mutex);
 	return ret;
 }
@@ -464,13 +507,45 @@
 				 mdm9625_mi2s_tx_ch_put),
 };
 
+static int msm9625_set_codec_mclk(struct snd_soc_pcm_runtime *rtd, bool enable)
+{
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	struct mdm_mi2s_clk *clk = &clk_ctl;
+	int ret = 0;
+
+	if (clk->clk_usrs == 0) {
+		clk->cdc_cr_clk = clk_get(cpu_dai->dev, "core_clk");
+		if (IS_ERR(clk->cdc_cr_clk)) {
+			pr_err("%s: Failed to Core clk %ld\n"
+			       "CPU dai name %s\n", __func__,
+			       PTR_ERR(clk->cdc_cr_clk),
+			       cpu_dai->dev->driver->name);
+			return -ENODEV ;
+		}
+		/* osr clock */
+		clk->cdc_osr_clk = clk_get(cpu_dai->dev, "osr_clk");
+		if (IS_ERR(clk->cdc_osr_clk)) {
+			pr_err("%s: Failed to request OSR %ld\n"
+			       "CPU dai name %s\n", __func__,
+			       PTR_ERR(clk->cdc_osr_clk),
+			       cpu_dai->dev->driver->name);
+			clk_put(clk->cdc_cr_clk);
+			return -ENODEV ;
+		}
+	} else {
+		pr_err("%s: Failed to get MCLK\n", __func__);
+		ret = -ENODEV ;
+	}
+	return ret;
+}
+
 static int mdm9625_mi2s_audrx_init(struct snd_soc_pcm_runtime *rtd)
 {
 	int err;
 	struct snd_soc_codec *codec = rtd->codec;
 	struct snd_soc_dapm_context *dapm = &codec->dapm;
 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-	pr_info("%s(), dev_name%s\n", __func__, dev_name(cpu_dai->dev));
+	pr_debug("%s(), dev_name%s\n", __func__, dev_name(cpu_dai->dev));
 
 	rtd->pmdown_time = 0;
 	err = snd_soc_add_codec_controls(codec, mdm_snd_controls,
@@ -491,8 +566,9 @@
 	snd_soc_dapm_sync(dapm);
 
 	/* start mbhc */
-	 mdm9625_set_mi2s_gpio();
-	mdm9625_mi2s_clk_ctl(rtd, true);
+	err = msm9625_set_codec_mclk(rtd, true);
+	if (err < 0)
+		return err;
 	mbhc_cfg.calibration = def_taiko_mbhc_cal();
 	if (mbhc_cfg.calibration)
 		err = taiko_hs_detect(codec, &mbhc_cfg);
@@ -683,14 +759,103 @@
 	.num_links = ARRAY_SIZE(mdm9625_dai),
 };
 
+static int mdm9625_dtparse_mi2s(struct platform_device *pdev,
+				struct mdm9625_machine_data **pdata)
+{
+	int ret = 0, i = 0;
+	struct msm_i2s_gpio *pin_data = NULL;
+	struct msm_i2s_ctrl *ctrl;
+	struct msm_i2s_gpio *mclk_pin = NULL;
+	unsigned int gpio_no[4];
+	unsigned int dt_mclk = 0;
+	enum of_gpio_flags flags = OF_GPIO_ACTIVE_LOW;
+	int prim_cnt = 0;
+	pin_data = devm_kzalloc(&pdev->dev, (4 *
+				sizeof(struct msm_i2s_gpio)),
+				GFP_KERNEL);
+	mclk_pin = devm_kzalloc(&pdev->dev,
+				sizeof(struct msm_i2s_gpio),
+				GFP_KERNEL);
+
+	if (!pin_data || !mclk_pin) {
+		dev_err(&pdev->dev, "No memory for gpio\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+	for (i = 0; i < ARRAY_SIZE(gpio_no); i++) {
+		gpio_no[i] = of_get_named_gpio_flags(pdev->dev.of_node,
+					  mdm_i2s_gpio_name[i][DT_PARSE_INDEX],
+					  0, &flags);
+		if (gpio_no[i] > 0) {
+			pin_data[i].gpio_name =
+				mdm_i2s_gpio_name[prim_cnt][GPIO_NAME_INDEX];
+			pin_data[i].gpio_no = gpio_no[i];
+			dev_dbg(&pdev->dev, "%s:GPIO gpio[%s] =\n"
+				"0x%x\n", __func__,
+				pin_data[i].gpio_name,
+				pin_data[i].gpio_no);
+			prim_cnt++;
+		} else {
+			dev_err(&pdev->dev, "%s:Invalid I2S GPIO[%s] = %x\n",
+				__func__,
+				mdm_i2s_gpio_name[i][GPIO_NAME_INDEX],
+				gpio_no[i]);
+			ret = -ENODEV;
+			goto err;
+		}
+	}
+	for (i = 0; i < ARRAY_SIZE(mdm_mclk_gpio); i++) {
+		dt_mclk = of_get_named_gpio_flags(pdev->dev.of_node,
+					  mdm_mclk_gpio[i][DT_PARSE_INDEX], 0,
+					  &flags);
+		if (dt_mclk > 0) {
+			mclk_pin->gpio_name =
+					mdm_mclk_gpio[i][GPIO_NAME_INDEX];
+			mclk_pin->gpio_no = dt_mclk;
+			ret = gpio_request(mclk_pin->gpio_no,
+					   mclk_pin->gpio_name);
+			dev_dbg(&pdev->dev, "%s:Request MCLK Gpio\n"
+				"gpio[%s] = 0x%x\n", __func__,
+				mclk_pin->gpio_name,
+				dt_mclk);
+		} else {
+			dev_err(&pdev->dev, "%s:MCLK gpio is incorrect\n",
+				__func__);
+			ret = -ENODEV;
+			goto err;
+		}
+	}
+
+	ctrl = devm_kzalloc(&pdev->dev,
+			    sizeof(struct msm_i2s_ctrl), GFP_KERNEL);
+	if (!ctrl) {
+		dev_err(&pdev->dev, "No memory for gpio\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+	ctrl->pin_data = pin_data;
+	ctrl->cnt = prim_cnt;
+	(*pdata)->pri_ctrl = ctrl;
+	(*pdata)->mclk_pin = mclk_pin;
+	return ret;
+
+err:
+	if (mclk_pin)
+		devm_kfree(&pdev->dev, mclk_pin);
+	if (pin_data)
+		devm_kfree(&pdev->dev, pin_data);
+	return ret;
+}
+
 static __devinit int mdm9625_asoc_machine_probe(struct platform_device *pdev)
 {
 	int ret;
 	struct snd_soc_card *card = &snd_soc_card_mdm9625;
+	struct mdm_mi2s_clk *clk = &clk_ctl;
 	struct mdm9625_machine_data *pdata;
 
 	mutex_init(&cdc_mclk_mutex);
-	gpio_enable = false;
+	clk->clk_usrs = 0;
 	if (!pdev->dev.of_node) {
 		dev_err(&pdev->dev, "No platform supplied from device tree\n");
 		return -EINVAL;
@@ -698,19 +863,17 @@
 	pdata = devm_kzalloc(&pdev->dev, sizeof(struct mdm9625_machine_data),
 			     GFP_KERNEL);
 	if (!pdata) {
-		dev_err(&pdev->dev, "Can't allocate msm8974_asoc_mach_data\n");
+		dev_err(&pdev->dev, "Can't allocate mdm9625_asoc_mach_data\n");
 		ret = -ENOMEM;
 		goto err;
 	}
-	card->dev = &pdev->dev;
-	platform_set_drvdata(pdev, card);
-	snd_soc_card_set_drvdata(card, pdata);
-	ret = snd_soc_of_parse_card_name(card, "qcom,model");
-	if (ret)
+	ret = mdm9625_dtparse_mi2s(pdev, &pdata);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"%s: mi2s Pin data parse failed",
+			__func__);
 		goto err;
-	ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing");
-	if (ret)
-		goto err;
+	}
 	ret = of_property_read_u32(pdev->dev.of_node,
 				   "qcom,taiko-mclk-clk-freq",
 				   &pdata->mclk_freq);
@@ -728,6 +891,15 @@
 		ret = -EINVAL;
 		goto err;
 	}
+	card->dev = &pdev->dev;
+	platform_set_drvdata(pdev, card);
+	snd_soc_card_set_drvdata(card, pdata);
+	ret = snd_soc_of_parse_card_name(card, "qcom,model");
+	if (ret)
+		goto err;
+	ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing");
+	if (ret)
+		goto err;
 	ret = snd_soc_register_card(card);
 	if (ret) {
 		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
diff --git a/sound/soc/msm/mpq8064.c b/sound/soc/msm/mpq8064.c
index cef8659..784d516 100644
--- a/sound/soc/msm/mpq8064.c
+++ b/sound/soc/msm/mpq8064.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012-2013, Code Aurora Forum. 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
@@ -1441,7 +1441,7 @@
 		.name = "MSM8960 Media3",
 		.stream_name = "MultiMedia3",
 		.cpu_dai_name	= "MultiMedia3",
-		.platform_name  = "msm-pcm-dsp",
+		.platform_name  = "msm-multi-ch-pcm-dsp",
 		.dynamic = 1,
 		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
 				SND_SOC_DPCM_TRIGGER_POST},
diff --git a/sound/soc/msm/msm-pcm-afe.c b/sound/soc/msm/msm-pcm-afe.c
index b7b4d51..f871f52 100644
--- a/sound/soc/msm/msm-pcm-afe.c
+++ b/sound/soc/msm/msm-pcm-afe.c
@@ -322,8 +322,8 @@
 				(app_cb)q6asm_event_handler, prtd);
 	if (!prtd->audio_client) {
 		pr_debug("%s: Could not allocate memory\n", __func__);
-		kfree(prtd);
 		mutex_unlock(&prtd->lock);
+		kfree(prtd);
 		return -ENOMEM;
 	}
 	hrtimer_init(&prtd->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 841d313..8237d81 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -71,6 +71,10 @@
 static const DECLARE_TLV_DB_LINEAR(multimedia5_rx_vol_gain, 0,
 			INT_RX_VOL_MAX_STEPS);
 
+static int msm_route_multimedia3_vol_control;
+static const DECLARE_TLV_DB_LINEAR(multimedia3_rx_vol_gain, 0,
+			INT_RX_VOL_MAX_STEPS);
+
 static int msm_route_compressed_vol_control;
 static const DECLARE_TLV_DB_LINEAR(compressed_rx_vol_gain, 0,
 			INT_RX_VOL_MAX_STEPS);
@@ -78,6 +82,10 @@
 static int msm_route_compressed2_vol_control;
 static const DECLARE_TLV_DB_LINEAR(compressed2_rx_vol_gain, 0,
 			INT_RX_VOL_MAX_STEPS);
+
+static int msm_route_compressed3_vol_control;
+static const DECLARE_TLV_DB_LINEAR(compressed3_rx_vol_gain, 0,
+			INT_RX_VOL_MAX_STEPS);
 static int msm_route_ec_ref_rx;
 
 /* Equal to Frontend after last of the MULTIMEDIA SESSIONS */
@@ -982,6 +990,23 @@
 	return 0;
 }
 
+static int msm_routing_get_multimedia3_vol_mixer(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	ucontrol->value.integer.value[0] = msm_route_multimedia3_vol_control;
+	return 0;
+}
+
+static int msm_routing_set_multimedia3_vol_mixer(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	if (!multi_ch_pcm_set_volume(ucontrol->value.integer.value[0]))
+		msm_route_multimedia3_vol_control =
+			ucontrol->value.integer.value[0];
+
+	return 0;
+}
+
 static int msm_routing_get_compressed_vol_mixer(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
@@ -1016,6 +1041,22 @@
 	return 0;
 }
 
+static int msm_routing_get_compressed3_vol_mixer(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	ucontrol->value.integer.value[0] = msm_route_compressed3_vol_control;
+	return 0;
+}
+
+static int msm_routing_set_compressed3_vol_mixer(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	if (!compressed_set_volume(ucontrol->value.integer.value[0]))
+		msm_route_compressed3_vol_control =
+			ucontrol->value.integer.value[0];
+	return 0;
+}
+
 static int msm_routing_get_srs_trumedia_control(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
 {
@@ -2124,6 +2165,12 @@
 	msm_routing_set_multimedia5_vol_mixer, multimedia5_rx_vol_gain),
 };
 
+static const struct snd_kcontrol_new multimedia3_vol_mixer_controls[] = {
+	SOC_SINGLE_EXT_TLV("HIFI4 RX Volume", SND_SOC_NOPM, 0,
+	INT_RX_VOL_GAIN, 0, msm_routing_get_multimedia3_vol_mixer,
+	msm_routing_set_multimedia3_vol_mixer, multimedia3_rx_vol_gain),
+};
+
 static const struct snd_kcontrol_new compressed_vol_mixer_controls[] = {
 	SOC_SINGLE_EXT_TLV("COMPRESSED RX Volume", SND_SOC_NOPM, 0,
 	INT_RX_VOL_GAIN, 0, msm_routing_get_compressed_vol_mixer,
@@ -2136,6 +2183,12 @@
 	msm_routing_set_compressed2_vol_mixer, compressed2_rx_vol_gain),
 };
 
+static const struct snd_kcontrol_new compressed3_vol_mixer_controls[] = {
+	SOC_SINGLE_EXT_TLV("COMPRESSED3 RX Volume", SND_SOC_NOPM, 0,
+	INT_RX_VOL_GAIN, 0, msm_routing_get_compressed3_vol_mixer,
+	msm_routing_set_compressed3_vol_mixer, compressed3_rx_vol_gain),
+};
+
 static const struct snd_kcontrol_new lpa_SRS_trumedia_controls[] = {
 	{.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name = "SRS TruMedia",
@@ -3188,13 +3241,22 @@
 			ARRAY_SIZE(multimedia5_vol_mixer_controls));
 
 	snd_soc_add_platform_controls(platform,
+				multimedia3_vol_mixer_controls,
+			ARRAY_SIZE(multimedia3_vol_mixer_controls));
+
+	snd_soc_add_platform_controls(platform,
 				compressed_vol_mixer_controls,
 			ARRAY_SIZE(compressed_vol_mixer_controls));
+
 	snd_soc_add_platform_controls(platform,
 				compressed2_vol_mixer_controls,
 			ARRAY_SIZE(compressed2_vol_mixer_controls));
 
 	snd_soc_add_platform_controls(platform,
+				compressed3_vol_mixer_controls,
+			ARRAY_SIZE(compressed3_vol_mixer_controls));
+
+	snd_soc_add_platform_controls(platform,
 				lpa_SRS_trumedia_controls,
 			ARRAY_SIZE(lpa_SRS_trumedia_controls));
 
diff --git a/sound/soc/msm/msm8930.c b/sound/soc/msm/msm8930.c
index bb9f2be..d674b8b 100644
--- a/sound/soc/msm/msm8930.c
+++ b/sound/soc/msm/msm8930.c
@@ -170,8 +170,12 @@
 				}
 			} else {
 
-				if (machine_is_msm8930_mtp()
-					|| machine_is_msm8930_fluid()) {
+				/*
+				 * 8930 CDP does not have a 5V speaker boost,
+				 * hence the GPIO enable for speaker boost is
+				 * only required for platforms other than CDP
+				 */
+				if (!machine_is_msm8930_cdp()) {
 					ret = msm8930_cfg_spkr_gpio(
 					  SPKR_BOOST_GPIO, 1, "SPKR_BOOST");
 					if (ret) {
@@ -208,8 +212,7 @@
 			return;
 		}
 
-		if (machine_is_msm8930_mtp()
-			|| machine_is_msm8930_fluid()) {
+		if (!machine_is_msm8930_cdp()) {
 			pr_debug("%s: Free speaker boost gpio %u\n",
 					__func__, SPKR_BOOST_GPIO);
 			gpio_direction_output(SPKR_BOOST_GPIO, 0);
diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
index 2f4c256..a7a80a6 100644
--- a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
@@ -1259,6 +1259,12 @@
 	SOC_ENUM_EXT("PRI MI2S TX Format", mi2s_config_enum[0],
 		     msm_dai_q6_mi2s_format_get,
 		     msm_dai_q6_mi2s_format_put),
+	SOC_ENUM_EXT("SEC MI2S RX Format", mi2s_config_enum[0],
+		     msm_dai_q6_mi2s_format_get,
+		     msm_dai_q6_mi2s_format_put),
+	SOC_ENUM_EXT("SEC MI2S TX Format", mi2s_config_enum[0],
+		     msm_dai_q6_mi2s_format_get,
+		     msm_dai_q6_mi2s_format_put),
 };
 
 static int msm_dai_q6_dai_mi2s_probe(struct snd_soc_dai *dai)
@@ -1267,26 +1273,37 @@
 			dev_get_drvdata(dai->dev);
 	struct snd_kcontrol *kcontrol = NULL;
 	int rc = 0;
+	const struct snd_kcontrol_new *ctrl = NULL;
 
 	if (mi2s_dai_data->rx_dai.mi2s_dai_data.port_config.i2s.channel_mode) {
-		kcontrol = snd_ctl_new1(&mi2s_config_controls[0],
+		if (!strncmp(dai->name, "msm-dai-q6-mi2s.0", 17))
+			ctrl = &mi2s_config_controls[0];
+		if (!strncmp(dai->name, "msm-dai-q6-mi2s.1", 17))
+			ctrl = &mi2s_config_controls[3];
+		kcontrol = snd_ctl_new1(ctrl,
 					&mi2s_dai_data->rx_dai.mi2s_dai_data);
 		rc = snd_ctl_add(dai->card->snd_card, kcontrol);
 
 		if (IS_ERR_VALUE(rc)) {
-			dev_err(dai->dev, "%s: err add RX fmt ctl\n", __func__);
+			dev_err(dai->dev, "%s: err add RX fmt ctl DAI = %s\n",
+				__func__, dai->name);
 			goto rtn;
 		}
 	}
 	if (mi2s_dai_data->tx_dai.mi2s_dai_data.port_config.i2s.channel_mode) {
+		if (!strncmp(dai->name, "msm-dai-q6-mi2s.0", 17))
+			ctrl = &mi2s_config_controls[2];
+		if (!strncmp(dai->name, "msm-dai-q6-mi2s.1", 17))
+			ctrl = &mi2s_config_controls[4];
 		rc = snd_ctl_add(dai->card->snd_card,
-				snd_ctl_new1(&mi2s_config_controls[2],
+				snd_ctl_new1(ctrl,
 				&mi2s_dai_data->tx_dai.mi2s_dai_data));
 
 		if (IS_ERR_VALUE(rc)) {
 			if (kcontrol)
 				snd_ctl_remove(dai->card->snd_card, kcontrol);
-			dev_err(dai->dev, "%s: err add TX fmt ctl\n", __func__);
+			dev_err(dai->dev, "%s: err add TX fmt ctl DAI = %s\n",
+				__func__, dai->name);
 		}
 	}
 rtn:
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 58300c4..26f634b 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -188,6 +188,8 @@
 	{ SLIMBUS_EXTPROC_RX, 0, 0, 0, 0, 0},
 	{ AFE_PORT_ID_QUATERNARY_MI2S_RX, 0, 0, 0, 0, 0},
 	{ AFE_PORT_ID_QUATERNARY_MI2S_TX, 0, 0, 0, 0, 0},
+	{ AFE_PORT_ID_SECONDARY_MI2S_RX, 0, 0, 0, 0, 0},
+	{ AFE_PORT_ID_SECONDARY_MI2S_TX, 0, 0, 0, 0, 0},
 };
 
 
@@ -1106,6 +1108,21 @@
 	msm_routing_put_audio_mixer),
 };
 
+static const struct snd_kcontrol_new secondary_mi2s_rx_mixer_controls[] = {
+	SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SECONDARY_MI2S_RX ,
+	MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+};
+
 static const struct snd_kcontrol_new hdmi_mixer_controls[] = {
 	SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_HDMI_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
@@ -1209,6 +1226,9 @@
 	SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
 		MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
 		msm_routing_put_audio_mixer),
+	SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_TX,
+		MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+		msm_routing_put_audio_mixer),
 	SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
 		MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
 		msm_routing_put_audio_mixer),
@@ -1852,11 +1872,14 @@
 	SND_SOC_DAPM_AIF_OUT("MI2S_RX", "MI2S Playback", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_RX", "Quaternary MI2S Playback",
 						0, 0, 0, 0),
-
+	SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX", "Secondary MI2S Playback",
+			     0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("PRI_I2S_TX", "Primary I2S Capture", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("MI2S_TX", "MI2S Capture", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("QUAT_MI2S_TX", "Quaternary MI2S Capture",
 						0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_IN("SEC_MI2S_TX", "Secondary MI2S Capture",
+			    0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("SLIMBUS_0_TX", "Slimbus Capture", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("INT_BT_SCO_RX", "Internal BT-SCO Playback",
 				0, 0, 0 , 0),
@@ -1919,6 +1942,9 @@
 	SND_SOC_DAPM_MIXER("QUAT_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
 				quaternary_mi2s_rx_mixer_controls,
 				ARRAY_SIZE(quaternary_mi2s_rx_mixer_controls)),
+	SND_SOC_DAPM_MIXER("SEC_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
+			   secondary_mi2s_rx_mixer_controls,
+			   ARRAY_SIZE(secondary_mi2s_rx_mixer_controls)),
 	SND_SOC_DAPM_MIXER("MultiMedia1 Mixer", SND_SOC_NOPM, 0, 0,
 	mmul1_mixer_controls, ARRAY_SIZE(mmul1_mixer_controls)),
 	SND_SOC_DAPM_MIXER("MultiMedia2 Mixer", SND_SOC_NOPM, 0, 0,
@@ -2068,6 +2094,13 @@
 	{"QUAT_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
 	{"QUAT_MI2S_RX", NULL, "QUAT_MI2S_RX Audio Mixer"},
 
+
+	{"SEC_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
+	{"SEC_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
+	{"SEC_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
+	{"SEC_MI2S_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+	{"SEC_MI2S_RX", NULL, "SEC_MI2S_RX Audio Mixer"},
+
 	{"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"},
 	{"MultiMedia1 Mixer", "MI2S_TX", "MI2S_TX"},
 	{"MultiMedia2 Mixer", "MI2S_TX", "MI2S_TX"},
@@ -2075,6 +2108,7 @@
 	{"MultiMedia1 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
 	{"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
 	{"MultiMedia2 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
+	{"MultiMedia1 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"},
 
 	{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
@@ -2249,10 +2283,11 @@
 	{"BE_OUT", NULL, "HDMI"},
 	{"BE_OUT", NULL, "MI2S_RX"},
 	{"BE_OUT", NULL, "QUAT_MI2S_RX"},
-
+	{"BE_OUT", NULL, "SEC_MI2S_RX"},
 	{"PRI_I2S_TX", NULL, "BE_IN"},
 	{"MI2S_TX", NULL, "BE_IN"},
 	{"QUAT_MI2S_TX", NULL, "BE_IN"},
+	{"SEC_MI2S_TX", NULL, "BE_IN"},
 	{"SLIMBUS_0_TX", NULL, "BE_IN" },
 	{"SLIMBUS_1_TX", NULL, "BE_IN" },
 	{"SLIMBUS_3_TX", NULL, "BE_IN" },
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
index be646ed..69b3fe3 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
@@ -35,6 +35,8 @@
 #define LPASS_BE_MI2S_TX "MI2S_TX"
 #define LPASS_BE_QUAT_MI2S_RX "QUAT_MI2S_RX"
 #define LPASS_BE_QUAT_MI2S_TX "QUAT_MI2S_TX"
+#define LPASS_BE_SEC_MI2S_RX "SEC_MI2S_RX"
+#define LPASS_BE_SEC_MI2S_TX "SEC_MI2S_TX"
 #define LPASS_BE_STUB_RX "STUB_RX"
 #define LPASS_BE_STUB_TX "STUB_TX"
 #define LPASS_BE_SLIMBUS_1_RX "SLIMBUS_1_RX"
@@ -99,6 +101,8 @@
 	MSM_BACKEND_DAI_EXTPROC_EC_TX,
 	MSM_BACKEND_DAI_QUATERNARY_MI2S_RX,
 	MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
+	MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
+	MSM_BACKEND_DAI_SECONDARY_MI2S_TX,
 	MSM_BACKEND_DAI_MAX,
 };
 
diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c
index 9387d21..d836610 100644
--- a/sound/soc/msm/qdsp6v2/q6afe.c
+++ b/sound/soc/msm/qdsp6v2/q6afe.c
@@ -174,6 +174,7 @@
 	case VOICE_PLAYBACK_TX:
 	case RT_PROXY_PORT_001_RX:
 	case AFE_PORT_ID_QUATERNARY_MI2S_RX:
+	case AFE_PORT_ID_SECONDARY_MI2S_RX:
 		ret = MSM_AFE_PORT_TYPE_RX;
 		break;
 
@@ -193,6 +194,7 @@
 	case INT_BT_SCO_TX:
 	case RT_PROXY_PORT_001_TX:
 	case AFE_PORT_ID_QUATERNARY_MI2S_TX:
+	case AFE_PORT_ID_SECONDARY_MI2S_TX:
 		ret = MSM_AFE_PORT_TYPE_TX;
 		break;
 
@@ -564,6 +566,11 @@
 		return IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX;
 	case AFE_PORT_ID_QUATERNARY_MI2S_TX:
 		return IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX;
+	case AFE_PORT_ID_SECONDARY_MI2S_RX:
+		return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX;
+	case AFE_PORT_ID_SECONDARY_MI2S_TX:
+		return IDX_AFE_PORT_ID_SECONDARY_MI2S_TX;
+
 	default: return -EINVAL;
 	}
 }
diff --git a/sound/soc/msm/qdsp6v2/q6audio-v2.c b/sound/soc/msm/qdsp6v2/q6audio-v2.c
index 033cb8e..5e2e618 100644
--- a/sound/soc/msm/qdsp6v2/q6audio-v2.c
+++ b/sound/soc/msm/qdsp6v2/q6audio-v2.c
@@ -52,6 +52,11 @@
 		return IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX;
 	case AFE_PORT_ID_QUATERNARY_MI2S_TX:
 		return IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX;
+	case AFE_PORT_ID_SECONDARY_MI2S_RX:
+		return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX;
+	case AFE_PORT_ID_SECONDARY_MI2S_TX:
+		return IDX_AFE_PORT_ID_SECONDARY_MI2S_TX;
+
 	default: return -EINVAL;
 	}
 }
@@ -89,6 +94,10 @@
 			     return AFE_PORT_ID_QUATERNARY_MI2S_RX;
 	case AFE_PORT_ID_QUATERNARY_MI2S_TX:
 			     return AFE_PORT_ID_QUATERNARY_MI2S_TX;
+	case AFE_PORT_ID_SECONDARY_MI2S_RX:
+			     return AFE_PORT_ID_SECONDARY_MI2S_RX;
+	case AFE_PORT_ID_SECONDARY_MI2S_TX:
+			     return AFE_PORT_ID_SECONDARY_MI2S_TX;
 
 	default: return -EINVAL;
 	}
@@ -147,6 +156,8 @@
 	case RT_PROXY_PORT_001_TX:
 	case AFE_PORT_ID_QUATERNARY_MI2S_RX:
 	case AFE_PORT_ID_QUATERNARY_MI2S_TX:
+	case AFE_PORT_ID_SECONDARY_MI2S_RX:
+	case AFE_PORT_ID_SECONDARY_MI2S_TX:
 	{
 		ret = 0;
 		break;