Merge "arm: handle discontig page struct between sections" into msm-3.0
diff --git a/arch/arm/configs/fsm9xxx-perf_defconfig b/arch/arm/configs/fsm9xxx-perf_defconfig
index 60d8a32..b6bc4f1 100644
--- a/arch/arm/configs/fsm9xxx-perf_defconfig
+++ b/arch/arm/configs/fsm9xxx-perf_defconfig
@@ -139,7 +139,6 @@
 # CONFIG_USB_SUPPORT is not set
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
-# CONFIG_LEDS_MSM_PMIC is not set
 CONFIG_SWITCH=y
 CONFIG_SWITCH_GPIO=y
 CONFIG_RTC_CLASS=y
diff --git a/arch/arm/configs/fsm9xxx_defconfig b/arch/arm/configs/fsm9xxx_defconfig
index 6913409..dd9797a 100644
--- a/arch/arm/configs/fsm9xxx_defconfig
+++ b/arch/arm/configs/fsm9xxx_defconfig
@@ -137,7 +137,6 @@
 # CONFIG_USB_SUPPORT is not set
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
-# CONFIG_LEDS_MSM_PMIC is not set
 CONFIG_SWITCH=y
 CONFIG_SWITCH_GPIO=y
 CONFIG_RTC_CLASS=y
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index 4322baf..162fc04 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -157,8 +157,9 @@
 CONFIG_BT_HCIUART_IBS=y
 CONFIG_BT_MSM_SLEEP=y
 CONFIG_MSM_BT_POWER=y
+CONFIG_CFG80211=y
+# CONFIG_CFG80211_WEXT is not set
 CONFIG_RFKILL=y
-CONFIG_RFKILL_PM=y
 CONFIG_MTD=y
 CONFIG_MTD_TESTS=m
 CONFIG_MTD_CMDLINE_PARTS=y
@@ -184,8 +185,6 @@
 CONFIG_SMSC911X=y
 # CONFIG_NETDEV_10000 is not set
 CONFIG_LIBRA_SDIOIF=m
-CONFIG_CFG80211=y
-CONFIG_CFG80211_WEXT=n
 # CONFIG_INPUT_MOUSEDEV is not set
 CONFIG_INPUT_EVDEV=y
 CONFIG_INPUT_EVBUG=m
@@ -194,7 +193,6 @@
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
 CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C=y
-CONFIG_SYNA_MULTI_TOUCH=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_UINPUT=y
 CONFIG_INPUT_GPIO=y
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index be8ade5..d19fa3d 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -155,8 +155,9 @@
 CONFIG_BT_HCIUART_IBS=y
 CONFIG_BT_MSM_SLEEP=y
 CONFIG_MSM_BT_POWER=y
+CONFIG_CFG80211=y
+# CONFIG_CFG80211_WEXT is not set
 CONFIG_RFKILL=y
-CONFIG_RFKILL_PM=y
 CONFIG_MTD=y
 CONFIG_MTD_TESTS=m
 CONFIG_MTD_CMDLINE_PARTS=y
@@ -182,8 +183,6 @@
 CONFIG_SMSC911X=y
 # CONFIG_NETDEV_10000 is not set
 CONFIG_LIBRA_SDIOIF=m
-CONFIG_CFG80211=y
-CONFIG_CFG80211_WEXT=n
 # CONFIG_INPUT_MOUSEDEV is not set
 CONFIG_INPUT_EVDEV=y
 CONFIG_INPUT_EVBUG=m
@@ -192,7 +191,6 @@
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
 CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C=y
-CONFIG_SYNA_MULTI_TOUCH=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_UINPUT=y
 CONFIG_INPUT_GPIO=y
diff --git a/arch/arm/configs/msm7630-perf_defconfig b/arch/arm/configs/msm7630-perf_defconfig
index 202d117..56710d7 100644
--- a/arch/arm/configs/msm7630-perf_defconfig
+++ b/arch/arm/configs/msm7630-perf_defconfig
@@ -71,7 +71,6 @@
 # CONFIG_INET_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
-CONFIG_INET_DIAG=y
 CONFIG_IPV6=y
 CONFIG_IPV6_PRIVACY=y
 CONFIG_IPV6_ROUTER_PREF=y
@@ -173,9 +172,10 @@
 CONFIG_BT_HCIUART_H4=y
 CONFIG_BT_HCIUART_IBS=y
 CONFIG_MSM_BT_POWER=y
+CONFIG_CFG80211=y
+# CONFIG_CFG80211_WEXT is not set
 # CONFIG_WIRELESS_EXT_SYSFS is not set
 CONFIG_RFKILL=y
-CONFIG_RFKILL_PM=y
 CONFIG_MTD=y
 CONFIG_MTD_TESTS=m
 CONFIG_MTD_CMDLINE_PARTS=y
@@ -208,8 +208,6 @@
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_LIBRA_SDIOIF=m
-CONFIG_CFG80211=y
-CONFIG_CFG80211_WEXT=n
 CONFIG_SLIP=y
 CONFIG_SLIP_COMPRESSED=y
 CONFIG_SLIP_MODE_SLIP6=y
@@ -326,7 +324,6 @@
 CONFIG_MMC_MSM_SDC2_8_BIT_SUPPORT=y
 CONFIG_MMC_MSM_SDC3_SUPPORT=y
 CONFIG_MMC_MSM_SDC4_SUPPORT=y
-# CONFIG_LEDS_MSM_PMIC is not set
 CONFIG_LEDS_PMIC8058=y
 CONFIG_SWITCH=y
 CONFIG_SWITCH_GPIO=y
diff --git a/arch/arm/configs/msm7630_defconfig b/arch/arm/configs/msm7630_defconfig
index bc944d0..115ce98 100644
--- a/arch/arm/configs/msm7630_defconfig
+++ b/arch/arm/configs/msm7630_defconfig
@@ -70,7 +70,6 @@
 # CONFIG_INET_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
-CONFIG_INET_DIAG=y
 CONFIG_IPV6=y
 CONFIG_IPV6_PRIVACY=y
 CONFIG_IPV6_ROUTER_PREF=y
@@ -172,9 +171,10 @@
 CONFIG_BT_HCIUART_H4=y
 CONFIG_BT_HCIUART_IBS=y
 CONFIG_MSM_BT_POWER=y
+CONFIG_CFG80211=y
+# CONFIG_CFG80211_WEXT is not set
 # CONFIG_WIRELESS_EXT_SYSFS is not set
 CONFIG_RFKILL=y
-CONFIG_RFKILL_PM=y
 CONFIG_MTD=y
 CONFIG_MTD_TESTS=m
 CONFIG_MTD_CMDLINE_PARTS=y
@@ -207,8 +207,6 @@
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_LIBRA_SDIOIF=m
-CONFIG_CFG80211=y
-CONFIG_CFG80211_WEXT=n
 CONFIG_SLIP=y
 CONFIG_SLIP_COMPRESSED=y
 CONFIG_SLIP_MODE_SLIP6=y
diff --git a/arch/arm/configs/msm8660-perf_defconfig b/arch/arm/configs/msm8660-perf_defconfig
index d377460..51c64d3 100644
--- a/arch/arm/configs/msm8660-perf_defconfig
+++ b/arch/arm/configs/msm8660-perf_defconfig
@@ -104,7 +104,6 @@
 # CONFIG_INET_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
-CONFIG_INET_DIAG=y
 CONFIG_IPV6=y
 CONFIG_IPV6_PRIVACY=y
 CONFIG_IPV6_ROUTER_PREF=y
@@ -212,9 +211,10 @@
 CONFIG_BT_HCIUART_H4=y
 CONFIG_BT_HCIUART_IBS=y
 CONFIG_MSM_BT_POWER=y
+CONFIG_CFG80211=y
+# CONFIG_CFG80211_WEXT is not set
 # CONFIG_WIRELESS_EXT_SYSFS is not set
 CONFIG_RFKILL=y
-CONFIG_RFKILL_PM=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_MISC_DEVICES=y
@@ -249,8 +249,6 @@
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_LIBRA_SDIOIF=m
-CONFIG_CFG80211=y
-CONFIG_CFG80211_WEXT=n
 CONFIG_PPP=y
 CONFIG_PPP_ASYNC=y
 CONFIG_PPP_DEFLATE=y
@@ -379,7 +377,6 @@
 CONFIG_MMC_MSM_SDC4_SUPPORT=y
 CONFIG_MMC_MSM_SDC5_SUPPORT=y
 CONFIG_LEDS_GPIO=y
-# CONFIG_LEDS_MSM_PMIC is not set
 CONFIG_LEDS_PMIC8058=y
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
diff --git a/arch/arm/configs/msm8660_defconfig b/arch/arm/configs/msm8660_defconfig
index 2569f82..e8708f3 100644
--- a/arch/arm/configs/msm8660_defconfig
+++ b/arch/arm/configs/msm8660_defconfig
@@ -95,7 +95,6 @@
 # CONFIG_INET_XFRM_MODE_TUNNEL is not set
 # CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_LRO is not set
-CONFIG_INET_DIAG=y
 CONFIG_IPV6=y
 CONFIG_IPV6_PRIVACY=y
 CONFIG_IPV6_ROUTER_PREF=y
@@ -203,9 +202,10 @@
 CONFIG_BT_HCIUART_H4=y
 CONFIG_BT_HCIUART_IBS=y
 CONFIG_MSM_BT_POWER=y
+CONFIG_CFG80211=y
+# CONFIG_CFG80211_WEXT is not set
 # CONFIG_WIRELESS_EXT_SYSFS is not set
 CONFIG_RFKILL=y
-CONFIG_RFKILL_PM=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_MISC_DEVICES=y
@@ -242,8 +242,6 @@
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_LIBRA_SDIOIF=m
-CONFIG_CFG80211=y
-CONFIG_CFG80211_WEXT=n
 CONFIG_PPP=y
 CONFIG_PPP_ASYNC=y
 CONFIG_PPP_DEFLATE=y
@@ -366,7 +364,6 @@
 CONFIG_MMC_MSM_SDC4_SUPPORT=y
 CONFIG_MMC_MSM_SDC5_SUPPORT=y
 CONFIG_LEDS_GPIO=y
-# CONFIG_LEDS_MSM_PMIC is not set
 CONFIG_LEDS_PMIC8058=y
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index c869beb..235db63 100755
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -355,6 +355,7 @@
 CONFIG_LEDS_PM8XXX=y
 # CONFIG_LEDS_MSM_PMIC is not set
 CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_SWITCH=y
 CONFIG_RTC_CLASS=y
 # CONFIG_RTC_DRV_MSM is not set
diff --git a/arch/arm/configs/msm9615_defconfig b/arch/arm/configs/msm9615_defconfig
index 714e630..4275140 100644
--- a/arch/arm/configs/msm9615_defconfig
+++ b/arch/arm/configs/msm9615_defconfig
@@ -41,6 +41,7 @@
 # CONFIG_MSM_PROC_COMM is not set
 CONFIG_MSM_SMD=y
 CONFIG_MSM_SMD_PKG4=y
+CONFIG_MSM_BAM_DMUX=y
 CONFIG_MSM_IPC_ROUTER=y
 CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
 CONFIG_MSM_DIRECT_SCLK_ACCESS=y
@@ -62,16 +63,35 @@
 CONFIG_VFP=y
 CONFIG_NEON=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+CONFIG_IPV6=y
+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET6_XFRM_MODE_BEET is not set
+# CONFIG_IPV6_SIT is not set
+# CONFIG_ANDROID_PARANOID_NETWORK is not set
+CONFIG_CFG80211=y
 CONFIG_MTD=y
 CONFIG_MTD_TESTS=m
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
-CONFIG_PM=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_MISC_DEVICES=y
 # CONFIG_ANDROID_PMEM is not set
+CONFIG_NETDEVICES=y
+CONFIG_HOSTAP=m
+# CONFIG_MSM_RMNET is not set
+CONFIG_MSM_RMNET_BAM=y
 # CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_KEYBOARD is not set
 # CONFIG_INPUT_MOUSE is not set
@@ -99,16 +119,10 @@
 CONFIG_SPI_SPIDEV=m
 CONFIG_DEBUG_GPIO=y
 CONFIG_GPIO_SYSFS=y
-CONFIG_HWMON=y
 CONFIG_SENSORS_PM8XXX_ADC=y
 CONFIG_THERMAL=y
 CONFIG_THERMAL_TSENS8960=y
 CONFIG_MFD_PM8018_CORE=y
-CONFIG_MFD_PM8XXX_PWM=y
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_PM8XXX=y
-# CONFIG_LEDS_MSM_PMIC is not set
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_GPIO=y
 # CONFIG_HID_SUPPORT is not set
@@ -116,56 +130,21 @@
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_CI13XXX_MSM=y
 CONFIG_USB_G_ANDROID=y
-CONFIG_SWITCH=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-CONFIG_IPV6=y
-# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET6_XFRM_MODE_BEET is not set
-# CONFIG_IPV6_SIT is not set
-# CONFIG_ANDROID_PARANOID_NETWORK is not set
-# CONFIG_WIRELESS is not set
 CONFIG_MMC=y
-# CONFIG_MMC_DEBUG is not set
 CONFIG_MMC_PERF_PROFILING=y
 CONFIG_MMC_UNSAFE_RESUME=y
-# CONFIG_MMC_CLKGATE is not set
 CONFIG_MMC_EMBEDDED_SDIO=y
 CONFIG_MMC_PARANOID_SD_INIT=y
-
-#
-# MMC/SD/SDIO Card Drivers
-#
-CONFIG_MMC_BLOCK=y
 CONFIG_MMC_BLOCK_MINORS=32
 # CONFIG_MMC_BLOCK_BOUNCE is not set
-# CONFIG_MMC_BLOCK_DEFERRED_RESUME is not set
-# CONFIG_SDIO_UART is not set
-# CONFIG_MMC_TEST is not set
-
-#
-# MMC/SD/SDIO Host Controller Drivers
-#
-# CONFIG_MMC_SDHCI is not set
 CONFIG_MMC_MSM=y
 CONFIG_MMC_MSM_SDIO_SUPPORT=y
 CONFIG_MMC_MSM_CARD_HW_DETECTION=y
-CONFIG_MMC_MSM_SDC1_SUPPORT=y
-# CONFIG_MMC_MSM_SDC1_8_BIT_SUPPORT is not set
-CONFIG_MMC_MSM_SDC2_SUPPORT=y
-# CONFIG_MMC_MSM_SDC2_8_BIT_SUPPORT is not set
-# CONFIG_MMC_MSM_SDC3_SUPPORT is not set
-# CONFIG_MMC_MSM_SDC4_SUPPORT is not set
-# CONFIG_MMC_MSM_SDC5_SUPPORT is not set
 CONFIG_MMC_MSM_SPS_SUPPORT=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_PM8XXX=y
+CONFIG_SWITCH=y
 CONFIG_RTC_CLASS=y
 # CONFIG_RTC_INTF_ALARM is not set
 # CONFIG_RTC_DRV_MSM is not set
@@ -178,6 +157,7 @@
 CONFIG_YAFFS_FS=y
 CONFIG_YAFFS_DISABLE_TAGS_ECC=y
 CONFIG_PARTITION_ADVANCED=y
+CONFIG_EFI_PARTITION=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ASCII=y
 CONFIG_NLS_ISO8859_1=y
@@ -205,29 +185,8 @@
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_TWOFISH=y
 CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_HW=y
 CONFIG_CRYPTO_DEV_QCRYPTO=m
 CONFIG_CRYPTO_DEV_QCE=m
 CONFIG_CRYPTO_DEV_QCEDEV=m
 CONFIG_CRC_CCITT=y
 CONFIG_LIBCRC32C=y
-
-CONFIG_WIRELESS=y
-CONFIG_WEXT_CORE=y
-CONFIG_WEXT_PROC=y
-CONFIG_CFG80211=y
-CONFIG_CFG80211_WEXT=y
-CONFIG_WIRELESS_EXT_SYSFS=y
-CONFIG_LIB80211=m
-CONFIG_NETDEVICES=y
-CONFIG_WLAN=y
-# CONFIG_MSM_RMNET is not set
-CONFIG_MSM_BAM_DMUX=y
-CONFIG_MSM_RMNET_BAM=y
-CONFIG_HOSTAP=m
-CONFIG_WIRELESS_EXT=y
-CONFIG_WEXT_SPY=y
-CONFIG_WEXT_PRIV=y
-CONFIG_LIB80211_CRYPT_WEP=m
-CONFIG_LIB80211_CRYPT_CCMP=m
-CONFIG_LIB80211_CRYPT_TKIP=m
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index f379b04..2f8bf62 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -348,8 +348,8 @@
  *  r13 = *virtual* address to jump to upon completion
  */
 __enable_mmu:
-#ifdef CONFIG_ALIGNMENT_TRAP
-	orr	r0, r0, #CR_A
+#if defined(CONFIG_ALIGNMENT_TRAP) && __LINUX_ARM_ARCH__ < 6
+      orr     r0, r0, #CR_A
 #else
 	bic	r0, r0, #CR_A
 #endif
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 66d1044..f3ae47e 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -176,6 +176,8 @@
 	select MIGRATION
 	select ARCH_MEMORY_PROBE
 	select ARCH_MEMORY_REMOVE
+	select DONT_RESERVE_FROM_MOVABLE_ZONE
+	select MSM_ULTRASOUND
 
 config ARCH_APQ8064
 	bool "APQ8064"
@@ -1587,6 +1589,7 @@
 config MSM_RPM_LOG
 	tristate "MSM Resource Power Manager Log Driver"
 	depends on DEBUG_FS
+	depends on MSM_RPM
 	default n
 	help
 	  This option enables a driver which can read from a circular buffer
@@ -1597,7 +1600,7 @@
 config MSM_RPM_STATS_LOG
 	tristate "MSM Resource Power Manager Stat Driver"
 	depends on DEBUG_FS
-	depends on ARCH_MSM8X60
+	depends on MSM_RPM
 	default n
 	  help
 	  This option enables a driver which reads RPM messages from a shared
@@ -1767,6 +1770,12 @@
           Enable HW audio support in QDSP6.
           QDSP6 can support HW encoder & decoder and audio processing
 
+config MSM_ULTRASOUND
+	bool "MSM ultrasound support"
+	depends on MSM_AUDIO_QDSP6
+	help
+	  Enable support for qdsp6/ultrasound.
+
 config MSM_RPC_VIBRATOR
 	bool "RPC based MSM Vibrator Support"
 	depends on MSM_ONCRPCROUTER
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index 0cd8a6e..d82a6bf 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -948,16 +948,10 @@
 
 static void vote_dfab(void)
 {
-	int rc;
-
-	rc = clk_enable(dfab_clk);
-	if (rc)
-		pr_err("bam_dmux vote for dfab failed rc = %d\n", rc);
 }
 
 static void unvote_dfab(void)
 {
-	clk_disable(dfab_clk);
 }
 
 static int restart_notifier_cb(struct notifier_block *this,
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index 755132b..b63f1a7 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -419,7 +419,7 @@
 		.gpio      = 26,
 		.settings = {
 			[GPIOMUX_ACTIVE]    = &sdcc2_cmd_data_0_3_actv_cfg,
-			[GPIOMUX_SUSPENDED] = &sdcc2_suspend_cfg,
+			[GPIOMUX_SUSPENDED] = &sdcc2_cmd_data_0_3_actv_cfg,
 		},
 	},
 	{
@@ -439,7 +439,7 @@
 		},
 	},
 	{
-		/* SDC2_CMD GSBI1 */
+		/* SDC2_CMD */
 		.gpio      = 29,
 		.settings = {
 			[GPIOMUX_ACTIVE]    = &sdcc2_cmd_data_0_3_actv_cfg,
@@ -447,7 +447,7 @@
 		},
 	},
 	{
-		/* SDC2_CLK GSBI1 */
+		/* SDC2_CLK */
 		.gpio      = 30,
 		.settings = {
 			[GPIOMUX_ACTIVE]    = &sdcc2_clk_actv_cfg,
@@ -509,6 +509,9 @@
 	.status_irq	= MSM_GPIO_TO_INT(GPIO_SDC1_HW_DET),
 	.irq_flags	= IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 #endif
+	.xpc_cap	= 1,
+	.uhs_caps	= (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
+			   MMC_CAP_MAX_CURRENT_400)
 };
 static struct mmc_platform_data *msm9615_sdc1_pdata = &sdc1_data;
 #else
@@ -650,6 +653,7 @@
 	&msm_device_sps,
 	&msm9615_device_tsens,
 	&msm_device_nand,
+	&msm_device_bam_dmux,
 	&msm_rpm_device,
 #ifdef CONFIG_HW_RANDOM_MSM
 	&msm_device_rng,
diff --git a/arch/arm/mach-msm/board-apq8064-regulator.c b/arch/arm/mach-msm/board-apq8064-regulator.c
index 59d0863..f8984f8 100644
--- a/arch/arm/mach-msm/board-apq8064-regulator.c
+++ b/arch/arm/mach-msm/board-apq8064-regulator.c
@@ -31,10 +31,14 @@
 VREG_CONSUMERS(L3) = {
 	REGULATOR_SUPPLY("8921_l3",		NULL),
 	REGULATOR_SUPPLY("HSUSB_3p3",		"msm_otg"),
+	REGULATOR_SUPPLY("HSUSB_3p3",		"msm_ehci_host.0"),
+	REGULATOR_SUPPLY("HSUSB_3p3",		"msm_ehci_host.1"),
 };
 VREG_CONSUMERS(L4) = {
 	REGULATOR_SUPPLY("8921_l4",		NULL),
 	REGULATOR_SUPPLY("HSUSB_1p8",		"msm_otg"),
+	REGULATOR_SUPPLY("HSUSB_1p8",		"msm_ehci_host.0"),
+	REGULATOR_SUPPLY("HSUSB_1p8",		"msm_ehci_host.1"),
 };
 VREG_CONSUMERS(L5) = {
 	REGULATOR_SUPPLY("8921_l5",		NULL),
@@ -108,6 +112,8 @@
 VREG_CONSUMERS(S3) = {
 	REGULATOR_SUPPLY("8921_s3",		NULL),
 	REGULATOR_SUPPLY("HSUSB_VDDCX",		"msm_otg"),
+	REGULATOR_SUPPLY("HSUSB_VDDCX",		"msm_ehci_host.0"),
+	REGULATOR_SUPPLY("HSUSB_VDDCX",		"msm_ehci_host.1"),
 };
 VREG_CONSUMERS(S4) = {
 	REGULATOR_SUPPLY("8921_s4",		NULL),
diff --git a/arch/arm/mach-msm/board-apq8064.c b/arch/arm/mach-msm/board-apq8064.c
index 88ce818..0e30aee 100644
--- a/arch/arm/mach-msm/board-apq8064.c
+++ b/arch/arm/mach-msm/board-apq8064.c
@@ -482,6 +482,7 @@
 }
 
 static struct platform_device *common_devices[] __initdata = {
+	&apq8064_device_dmov,
 	&apq8064_device_qup_i2c_gsbi4,
 	&apq8064_device_qup_spi_gsbi5,
 	&apq8064_slim_ctrl,
@@ -498,7 +499,6 @@
 };
 
 static struct platform_device *sim_devices[] __initdata = {
-	&apq8064_device_dmov,
 	&apq8064_device_uart_gsbi3,
 	&msm_device_sps_apq8064,
 };
diff --git a/arch/arm/mach-msm/board-dt.c b/arch/arm/mach-msm/board-dt.c
index 1ede17b..1a085de 100644
--- a/arch/arm/mach-msm/board-dt.c
+++ b/arch/arm/mach-msm/board-dt.c
@@ -21,11 +21,6 @@
 #include <mach/board.h>
 #include "timer.h"
 
-#define early_machine_is_copper()	\
-	of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,msmcopper")
-#define machine_is_copper()		\
-	of_machine_is_compatible("qcom,msmcopper")
-
 static void __init msm_dt_init_irq(void)
 {
 	if (machine_is_copper())
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index ca1da75..1435774 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -1070,12 +1070,19 @@
 
 #ifdef CONFIG_ARCH_MSM7X27A
 #define MSM_PMEM_MDP_SIZE       0x1900000
+#define MSM7x25A_MSM_PMEM_MDP_SIZE	0x1000000
+
 #define MSM_PMEM_ADSP_SIZE      0x1000000
+#define MSM7x25A_MSM_PMEM_ADSP_SIZE      0xB91000
+
 
 #ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
 #define MSM_FB_SIZE		0x260000
+#define MSM7x25A_MSM_FB_SIZE	0xE1000
 #else
 #define MSM_FB_SIZE		0x195000
+#define MSM7x25A_MSM_FB_SIZE	0xE1000
+
 #endif
 
 #endif
@@ -2568,7 +2575,12 @@
 	void *addr;
 	unsigned long size;
 
-	size = fb_size ? : MSM_FB_SIZE;
+	if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa())
+		fb_size = MSM7x25A_MSM_FB_SIZE;
+	else
+		fb_size = MSM_FB_SIZE;
+
+	size = fb_size;
 	addr = alloc_bootmem_align(size, 0x1000);
 	msm_fb_resources[0].start = __pa(addr);
 	msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1;
@@ -2589,6 +2601,15 @@
 
 static void __init size_pmem_devices(void)
 {
+
+	if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
+		pmem_mdp_size = MSM7x25A_MSM_PMEM_MDP_SIZE;
+		pmem_adsp_size = MSM7x25A_MSM_PMEM_ADSP_SIZE;
+	} else {
+		pmem_mdp_size = MSM_PMEM_MDP_SIZE;
+		pmem_adsp_size = MSM_PMEM_ADSP_SIZE;
+	}
+
 #ifdef CONFIG_ANDROID_PMEM
 	android_pmem_adsp_pdata.size = pmem_adsp_size;
 	android_pmem_pdata.size = pmem_mdp_size;
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index 9fb9fb6..9155e0c 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -6366,6 +6366,11 @@
 #ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
 	if (machine_is_msm8x55_svlte_surf())
 		msm7x30_sdc2_data.msmsdcc_fmax =  24576000;
+	if (machine_is_msm8x55_svlte_surf() ||
+			machine_is_msm8x55_svlte_ffa()) {
+		msm7x30_sdc2_data.sdiowakeup_irq = MSM_GPIO_TO_INT(68);
+		msm7x30_sdc2_data.is_sdio_al_client = 1;
+	}
 	sdcc_vreg_data[1].vreg_data = vreg_s3;
 	sdcc_vreg_data[1].level = 1800;
 	msm_add_sdcc(2, &msm7x30_sdc2_data);
diff --git a/arch/arm/mach-msm/board-msm8960-regulator.c b/arch/arm/mach-msm/board-msm8960-regulator.c
index 29b7460..de2a94e 100644
--- a/arch/arm/mach-msm/board-msm8960-regulator.c
+++ b/arch/arm/mach-msm/board-msm8960-regulator.c
@@ -231,6 +231,7 @@
 	REGULATOR_SUPPLY("ext_3p3v",		NULL),
 	REGULATOR_SUPPLY("vdd",			"3-005b"),
 	REGULATOR_SUPPLY("vdd_lvds_3p3v",	"mipi_dsi.1"),
+	REGULATOR_SUPPLY("mhl_ext_3p3v",	"msm_otg"),
 };
 
 #define PM8921_VREG_INIT(_id, _min_uV, _max_uV, _modes, _ops, _apply_uV, \
diff --git a/arch/arm/mach-msm/board-msm8960.c b/arch/arm/mach-msm/board-msm8960.c
index c264011..3e3d257 100644
--- a/arch/arm/mach-msm/board-msm8960.c
+++ b/arch/arm/mach-msm/board-msm8960.c
@@ -206,7 +206,6 @@
 	}
 }
 
-#define FPGA_CS_GPIO		14
 #define KS8851_RST_GPIO		89
 #define KS8851_IRQ_GPIO		90
 
@@ -241,6 +240,18 @@
 	.pull = GPIOMUX_PULL_DOWN,
 };
 
+static struct gpiomux_setting spi_active_config2 = {
+	.func = GPIOMUX_FUNC_2,
+	.drv = GPIOMUX_DRV_8MA,
+	.pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting spi_suspended_config2 = {
+	.func = GPIOMUX_FUNC_GPIO,
+	.drv = GPIOMUX_DRV_2MA,
+	.pull = GPIOMUX_PULL_UP,
+};
+
 static struct gpiomux_setting gsbi3_suspended_cfg = {
 	.func = GPIOMUX_FUNC_1,
 	.drv = GPIOMUX_DRV_2MA,
@@ -320,12 +331,6 @@
 			[GPIOMUX_SUSPENDED] = &gpio_eth_config,
 		}
 	},
-	{
-		.gpio = FPGA_CS_GPIO,
-		.settings = {
-			[GPIOMUX_SUSPENDED] = &gpio_eth_config,
-		}
-	},
 #endif
 };
 
@@ -359,6 +364,13 @@
 		},
 	},
 	{
+		.gpio      = 14,		/* GSBI1 SPI_CS_1 */
+		.settings = {
+			[GPIOMUX_SUSPENDED] = &spi_suspended_config2,
+			[GPIOMUX_ACTIVE] = &spi_active_config2,
+		},
+	},
+	{
 		.gpio      = 16,	/* GSBI3 I2C QUP SDA */
 		.settings = {
 			[GPIOMUX_SUSPENDED] = &gsbi3_suspended_cfg,
@@ -1969,6 +1981,7 @@
 	}
 };
 
+#define FPGA_3D_GPIO_CONFIG_ADDR	0xB5
 static int dsi2lvds_gpio[2] = {
 	0,/* Backlight PWM-ID=0 for PMIC-GPIO#24 */
 	0x1F08 /* DSI2LVDS Bridge GPIO Output, mask=0x1f, out=0x08 */
@@ -1994,6 +2007,8 @@
 };
 
 static struct mipi_dsi_panel_platform_data novatek_pdata = {
+	.fpga_3d_config_addr  = FPGA_3D_GPIO_CONFIG_ADDR,
+	.fpga_ctrl_mode = FPGA_SPI_INTF,
 	.phy_ctrl_settings = &dsi_novatek_cmd_mode_phy_db,
 };
 
@@ -2053,6 +2068,14 @@
 };
 #endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL */
 
+#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
+static struct platform_device wfd_panel_device = {
+	.name = "wfd_panel",
+	.id = 0,
+	.dev.platform_data = NULL,
+};
+#endif
+
 #ifdef CONFIG_MSM_BUS_SCALING
 static struct msm_bus_vectors dtv_bus_init_vectors[] = {
 	{
@@ -3605,6 +3628,13 @@
 		.mode                   = SPI_MODE_0,
 		.platform_data		= &spi_eth_pdata
 	},
+	{
+		.modalias               = "dsi_novatek_3d_panel_spi",
+		.max_speed_hz           = 10800000,
+		.bus_num                = 0,
+		.chip_select            = 1,
+		.mode                   = SPI_MODE_0,
+	},
 };
 
 static struct platform_device msm_device_saw_core0 = {
@@ -3751,6 +3781,7 @@
 	&ion_dev,
 #endif
 	&msm_rpm_log_device,
+	&msm_rpm_stat_device,
 #ifdef CONFIG_MSM_QDSS
 	&msm_etb_device,
 	&msm_tpiu_device,
@@ -3759,6 +3790,9 @@
 #endif
 	&msm_device_dspcrashd_8960,
 	&msm8960_device_watchdog,
+#ifdef CONFIG_FB_MSM_WRITEBACK_MSM_PANEL
+	&wfd_panel_device,
+#endif
 };
 
 static struct platform_device *sim_devices[] __initdata = {
@@ -4226,30 +4260,6 @@
 	},
 };
 
-#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
-static int fpga_init(void)
-{
-	int ret;
-
-	ret = gpio_request(FPGA_CS_GPIO, "fpga_cs");
-	if (ret) {
-		pr_err("FPGA CS gpio_request failed: %d\n", ret);
-		goto fail;
-	}
-
-	gpio_direction_output(FPGA_CS_GPIO, 1);
-
-	return 0;
-fail:
-	return ret;
-}
-#else
-static int fpga_init(void)
-{
-	return 0;
-}
-#endif
-
 static struct msm_cpuidle_state msm_cstates[] __initdata = {
 	{0, 0, "C0", "WFI",
 		MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT},
@@ -4627,6 +4637,8 @@
 		pr_err("Failed to initialize XO votes\n");
 	platform_device_register(&msm8960_device_rpm_regulator);
 	msm_clock_init(&msm8960_clock_init_data);
+	if (machine_is_msm8960_liquid())
+		msm_otg_pdata.mhl_enable = true;
 	msm8960_device_otg.dev.platform_data = &msm_otg_pdata;
 	msm8960_device_gadget_peripheral.dev.parent = &msm8960_device_otg.dev;
 	msm_device_hsusb_host.dev.parent = &msm8960_device_otg.dev;
@@ -4638,8 +4650,6 @@
 #endif
 	msm_device_hsic_host.dev.platform_data = &msm_hsic_pdata;
 	gpiomux_init();
-	if (machine_is_msm8960_cdp())
-		fpga_init();
 	if (machine_is_msm8960_liquid())
 		pm8921_platform_data.keypad_pdata = &keypad_data_liquid;
 	msm8960_device_qup_spi_gsbi1.dev.platform_data =
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 455644f..b394710 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -747,12 +747,14 @@
 }
 
 #define PMIC_GPIO_HAP_ENABLE   18  /* PMIC GPIO Number 19 */
+#define PMIC_GPIO_HAP_LDO_ENABLE   5  /* PMIC GPIO Number 6 */
 static struct isa1200_platform_data isa1200_1_pdata = {
 	.name = "vibrator",
 	.power_on = isa1200_power,
 	.dev_setup = isa1200_dev_setup,
 	/*gpio to enable haptic*/
 	.hap_en_gpio = PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_HAP_ENABLE),
+	.hap_len_gpio = PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_HAP_LDO_ENABLE),
 	.max_timeout = 15000,
 	.mode_ctrl = PWM_GEN_MODE,
 	.pwm_fd = {
@@ -991,6 +993,7 @@
 static struct regulator *ldo7_1p8;
 static struct regulator *vdd_cx;
 #define PMICID_INT		PM8058_GPIO_IRQ(PM8058_IRQ_BASE, 36)
+#define PMIC_ID_GPIO		36
 notify_vbus_state notify_vbus_state_func_ptr;
 static int usb_phy_susp_dig_vol = 750000;
 static int pmic_id_notif_supported;
@@ -1029,10 +1032,42 @@
 	return IRQ_HANDLED;
 }
 
+static int msm_hsusb_phy_id_setup_init(int init)
+{
+	unsigned ret;
+
+	if (init) {
+		ret = pm8901_mpp_config_digital_out(1,
+			PM8901_MPP_DIG_LEVEL_L5, 1);
+		if (ret < 0)
+			pr_err("%s:MPP2 configuration failed\n", __func__);
+	} else {
+		ret = pm8901_mpp_config_digital_out(1,
+			PM8901_MPP_DIG_LEVEL_L5, 0);
+		if (ret < 0)
+			pr_err("%s:MPP2 un config failed\n", __func__);
+	}
+	return ret;
+}
+
 static int msm_hsusb_pmic_id_notif_init(void (*callback)(int online), int init)
 {
 	unsigned ret = -ENODEV;
 
+	struct pm8058_gpio pmic_id_cfg = {
+		.direction	= PM_GPIO_DIR_IN,
+		.pull		= PM_GPIO_PULL_UP_1P5,
+		.function	= PM_GPIO_FUNC_NORMAL,
+		.vin_sel	= 2,
+		.inv_int_pol	= 0,
+	};
+	struct pm8058_gpio pmic_id_uncfg = {
+		.direction	= PM_GPIO_DIR_IN,
+		.pull		= PM_GPIO_PULL_NO,
+		.function	= PM_GPIO_FUNC_NORMAL,
+		.vin_sel	= 2,
+		.inv_int_pol	= 0,
+	};
 	if (!callback)
 		return -EINVAL;
 
@@ -1056,37 +1091,34 @@
 
 	if (init) {
 		notify_vbus_state_func_ptr = callback;
-		ret = pm8901_mpp_config_digital_out(1,
-			PM8901_MPP_DIG_LEVEL_L5, 1);
-		if (ret) {
-			pr_err("%s: MPP2 configuration failed\n", __func__);
-			return -ENODEV;
-		}
 		INIT_DELAYED_WORK(&pmic_id_det, pmic_id_detect);
+		ret = pm8058_gpio_config(PMIC_ID_GPIO, &pmic_id_cfg);
+		if (ret) {
+			pr_err("%s:return val of pm8058_gpio_config: %d\n",
+						__func__,  ret);
+			return ret;
+		}
 		ret = request_threaded_irq(PMICID_INT, NULL, pmic_id_on_irq,
 			(IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING),
 						"msm_otg_id", NULL);
 		if (ret) {
-			pm8901_mpp_config_digital_out(1,
-					PM8901_MPP_DIG_LEVEL_L5, 0);
 			pr_err("%s:pmic_usb_id interrupt registration failed",
 					__func__);
 			return ret;
 		}
-		/* Notify the initial Id status */
-		pmic_id_detect(&pmic_id_det.work);
 		msm_otg_pdata.pmic_id_irq = PMICID_INT;
 	} else {
+		usb_phy_susp_dig_vol = 750000;
 		free_irq(PMICID_INT, 0);
+		ret = pm8058_gpio_config(PMIC_ID_GPIO, &pmic_id_uncfg);
+		if (ret) {
+			pr_err("%s: return val of pm8058_gpio_config: %d\n",
+						__func__,  ret);
+			return ret;
+		}
 		msm_otg_pdata.pmic_id_irq = 0;
 		cancel_delayed_work_sync(&pmic_id_det);
 		notify_vbus_state_func_ptr = NULL;
-		ret = pm8901_mpp_config_digital_out(1,
-			PM8901_MPP_DIG_LEVEL_L5, 0);
-		if (ret) {
-			pr_err("%s:MPP2 configuration failed\n", __func__);
-			return -ENODEV;
-		}
 	}
 	return 0;
 }
@@ -1391,6 +1423,7 @@
 	.bam_disable		 = 1,
 #ifdef CONFIG_USB_EHCI_MSM_72K
 	.pmic_id_notif_init = msm_hsusb_pmic_id_notif_init,
+	.phy_id_setup_init = msm_hsusb_phy_id_setup_init,
 #endif
 #ifdef CONFIG_USB_EHCI_MSM_72K
 	.vbus_power = msm_hsusb_vbus_power,
@@ -5346,6 +5379,7 @@
 
 #ifdef CONFIG_PMIC8058
 #define PMIC_GPIO_SDC3_DET 22
+#define PMIC_GPIO_TOUCH_DISC_INTR 5
 
 static int pm8058_gpios_init(void)
 {
@@ -5409,16 +5443,6 @@
 				.inv_int_pol    = 0,
 			},
 		},
-		{ /* TouchDisc Interrupt */
-			5,
-			{
-				.direction      = PM_GPIO_DIR_IN,
-				.pull           = PM_GPIO_PULL_UP_1P5,
-				.vin_sel        = 2,
-				.function       = PM_GPIO_FUNC_NORMAL,
-				.inv_int_pol    = 0,
-			}
-		},
 		{ /* Timpani Reset */
 			20,
 			{
@@ -5436,7 +5460,7 @@
 			36,
 			{
 				.direction	= PM_GPIO_DIR_IN,
-				.pull		= PM_GPIO_PULL_UP_1P5,
+				.pull		= PM_GPIO_PULL_NO,
 				.function	= PM_GPIO_FUNC_NORMAL,
 				.vin_sel	= 2,
 				.inv_int_pol	= 0,
@@ -5444,22 +5468,27 @@
 		},
 	};
 
+#if defined(CONFIG_TOUCHDISC_VTD518_SHINETSU) || \
+		defined(CONFIG_TOUCHDISC_VTD518_SHINETSU_MODULE)
+	struct pm8058_gpio touchdisc_intr_gpio_cfg = {
+		.direction      = PM_GPIO_DIR_IN,
+		.pull           = PM_GPIO_PULL_UP_1P5,
+		.vin_sel        = 2,
+		.function       = PM_GPIO_FUNC_NORMAL,
+	};
+#endif
+
 #if defined(CONFIG_HAPTIC_ISA1200) || \
-		defined(CONFIG_HAPTIC_ISA1200_MODULE)
-
-	struct pm8058_gpio_cfg en_hap_gpio_cfg = {
-			PMIC_GPIO_HAP_ENABLE,
-			{
-				.direction      = PM_GPIO_DIR_OUT,
-				.pull           = PM_GPIO_PULL_NO,
-				.out_strength   = PM_GPIO_STRENGTH_HIGH,
-				.function       = PM_GPIO_FUNC_NORMAL,
-				.inv_int_pol    = 0,
-				.vin_sel        = 2,
-				.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
-				.output_value   = 0,
-			}
-
+			defined(CONFIG_HAPTIC_ISA1200_MODULE)
+	struct pm8058_gpio en_hap_gpio_cfg = {
+		.direction      = PM_GPIO_DIR_OUT,
+		.pull           = PM_GPIO_PULL_NO,
+		.out_strength   = PM_GPIO_STRENGTH_HIGH,
+		.function       = PM_GPIO_FUNC_NORMAL,
+		.inv_int_pol    = 0,
+		.vin_sel        = 2,
+		.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
+		.output_value   = 0,
 	};
 #endif
 
@@ -5508,15 +5537,35 @@
 		}
 	};
 #endif
+
 #if defined(CONFIG_HAPTIC_ISA1200) || \
 			defined(CONFIG_HAPTIC_ISA1200_MODULE)
 	if (machine_is_msm8x60_fluid()) {
-		rc = pm8058_gpio_config(en_hap_gpio_cfg.gpio,
-				&en_hap_gpio_cfg.cfg);
+		rc = pm8058_gpio_config(PMIC_GPIO_HAP_ENABLE,
+				&en_hap_gpio_cfg);
 		if (rc < 0) {
-			pr_err("%s pmic haptics gpio config failed\n",
+			pr_err("%s: pmic haptics gpio config failed\n",
 							__func__);
-			return rc;
+		}
+		rc = pm8058_gpio_config(PMIC_GPIO_HAP_LDO_ENABLE,
+				&en_hap_gpio_cfg);
+		if (rc < 0) {
+			pr_err("%s: pmic haptics ldo gpio config failed\n",
+							__func__);
+		}
+
+	}
+#endif
+
+#if defined(CONFIG_TOUCHDISC_VTD518_SHINETSU) || \
+		defined(CONFIG_TOUCHDISC_VTD518_SHINETSU_MODULE)
+	if (machine_is_msm8x60_ffa() || machine_is_msm8x60_surf() ||
+		machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa()) {
+		rc = pm8058_gpio_config(PMIC_GPIO_TOUCH_DISC_INTR,
+				&touchdisc_intr_gpio_cfg);
+		if (rc < 0) {
+			pr_err("%s: Touchdisc interrupt gpio config failed\n",
+							__func__);
 		}
 	}
 #endif
diff --git a/arch/arm/mach-msm/clock-7x30.c b/arch/arm/mach-msm/clock-7x30.c
index 5df1700..9fa13e5 100644
--- a/arch/arm/mach-msm/clock-7x30.c
+++ b/arch/arm/mach-msm/clock-7x30.c
@@ -2550,7 +2550,7 @@
 }
 
 /* Sample clock for 'tcxo4_ticks' reference clock ticks. */
-static u32 run_measurement(unsigned tcxo4_ticks)
+static unsigned long run_measurement(unsigned tcxo4_ticks)
 {
 	/* TCXO4_CNT_EN and RINGOSC_CNT_EN register values. */
 	u32 reg_val_enable = readl_relaxed(MISC_CLK_CTL_BASE_REG) | 0x3;
@@ -2573,7 +2573,7 @@
 
 /* Perform a hardware rate measurement for a given clock.
    FOR DEBUG USE ONLY: Measurements take ~15 ms! */
-static unsigned measure_clk_get_rate(struct clk *clk)
+static unsigned long measure_clk_get_rate(struct clk *clk)
 {
 	unsigned long flags;
 	u32 regval, prph_web_reg_old;
@@ -2626,7 +2626,7 @@
 	return -EINVAL;
 }
 
-static unsigned measure_clk_get_rate(struct clk *clk)
+static unsigned long measure_clk_get_rate(struct clk *clk)
 {
 	return 0;
 }
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 37dabc8..6521537 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -2934,7 +2934,7 @@
 
 struct pix_rdi_clk {
 	bool enabled;
-	unsigned cur_rate;
+	unsigned long cur_rate;
 
 	void __iomem *const s_reg;
 	u32 s_mask;
@@ -2951,7 +2951,7 @@
 	return container_of(clk, struct pix_rdi_clk, c);
 }
 
-static int pix_rdi_clk_set_rate(struct clk *c, unsigned rate)
+static int pix_rdi_clk_set_rate(struct clk *c, unsigned long rate)
 {
 	int ret, i;
 	u32 reg;
@@ -3011,7 +3011,7 @@
 	return 0;
 }
 
-static unsigned pix_rdi_clk_get_rate(struct clk *c)
+static unsigned long pix_rdi_clk_get_rate(struct clk *c)
 {
 	return to_pix_rdi_clk(c)->cur_rate;
 }
@@ -3982,7 +3982,7 @@
 	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
 }
 
-static unsigned hdmi_pll_clk_get_rate(struct clk *clk)
+static unsigned long hdmi_pll_clk_get_rate(struct clk *clk)
 {
 	return hdmi_pll_get_rate();
 }
@@ -4970,7 +4970,7 @@
 
 /* Perform a hardware rate measurement for a given clock.
    FOR DEBUG USE ONLY: Measurements take ~15 ms! */
-static unsigned measure_clk_get_rate(struct clk *c)
+static unsigned long measure_clk_get_rate(struct clk *c)
 {
 	unsigned long flags;
 	u32 pdm_reg_backup, ringosc_reg_backup;
@@ -5023,7 +5023,7 @@
 	return -EINVAL;
 }
 
-static unsigned measure_clk_get_rate(struct clk *clk)
+static unsigned long measure_clk_get_rate(struct clk *clk)
 {
 	return 0;
 }
@@ -5044,7 +5044,7 @@
 	.multiplier = 1,
 };
 
-static struct clk_lookup msm_clocks_8064[] __initdata = {
+static struct clk_lookup msm_clocks_8064[] = {
 	CLK_LOOKUP("cxo",		cxo_clk.c,		NULL),
 	CLK_LOOKUP("pll2",		pll2_clk.c,		NULL),
 	CLK_LOOKUP("pll8",		pll8_clk.c,		NULL),
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index c5d3d1d..6707757 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -3466,7 +3466,7 @@
 
 /* Perform a hardware rate measurement for a given clock.
    FOR DEBUG USE ONLY: Measurements take ~15 ms! */
-static unsigned measure_clk_get_rate(struct clk *c)
+static unsigned long measure_clk_get_rate(struct clk *c)
 {
 	unsigned long flags;
 	u32 pdm_reg_backup, ringosc_reg_backup;
@@ -3520,7 +3520,7 @@
 	return -EINVAL;
 }
 
-static unsigned measure_clk_get_rate(struct clk *clk)
+static unsigned long measure_clk_get_rate(struct clk *clk)
 {
 	return 0;
 }
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index dca8268..8ff9725 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -194,11 +194,10 @@
 
 static int set_vdd_dig(struct clk_vdd_class *vdd_class, int level)
 {
-	/* TODO: Update these voltages when info becomes available. */
 	static const int vdd_uv[] = {
-		[VDD_DIG_NONE]    = 1150000,
-		[VDD_DIG_LOW]     = 1150000,
-		[VDD_DIG_NOMINAL] = 1150000,
+		[VDD_DIG_NONE]    =       0,
+		[VDD_DIG_LOW]     =  945000,
+		[VDD_DIG_NOMINAL] = 1050000,
 		[VDD_DIG_HIGH]    = 1150000
 	};
 
@@ -1407,7 +1406,7 @@
 }
 
 /* Sample clock for 'ticks' reference clock ticks. */
-static u32 run_measurement(unsigned ticks)
+static unsigned long run_measurement(unsigned ticks)
 {
 	/* Stop counters and set the XO4 counter start value. */
 	writel_relaxed(ticks, RINGOSC_TCXO_CTL_REG);
@@ -1431,7 +1430,7 @@
 
 /* Perform a hardware rate measurement for a given clock.
    FOR DEBUG USE ONLY: Measurements take ~15 ms! */
-static unsigned measure_clk_get_rate(struct clk *c)
+static unsigned long measure_clk_get_rate(struct clk *c)
 {
 	unsigned long flags;
 	u32 pdm_reg_backup, ringosc_reg_backup;
@@ -1484,7 +1483,7 @@
 	return -EINVAL;
 }
 
-static unsigned measure_clk_get_rate(struct clk *clk)
+static unsigned long measure_clk_get_rate(struct clk *clk)
 {
 	return 0;
 }
diff --git a/arch/arm/mach-msm/clock-debug.c b/arch/arm/mach-msm/clock-debug.c
index ab4d8c1..78586a8 100644
--- a/arch/arm/mach-msm/clock-debug.c
+++ b/arch/arm/mach-msm/clock-debug.c
@@ -141,9 +141,24 @@
 	return ret;
 }
 
+
+static int clock_debug_print_clock(struct clk *c)
+{
+	size_t ln = 0;
+	char s[128];
+
+	if (!c || !c->count)
+		return 0;
+
+	ln += snprintf(s, sizeof(s), "\t%s", c->dbg_name);
+	while (ln < sizeof(s) && (c = clk_get_parent(c)))
+		ln += snprintf(s + ln, sizeof(s) - ln, " -> %s", c->dbg_name);
+	pr_info("%s\n", s);
+	return 1;
+}
+
 void clock_debug_print_enabled(void)
 {
-	struct clk *clk;
 	unsigned i;
 	int cnt = 0;
 
@@ -151,14 +166,8 @@
 		return;
 
 	pr_info("Enabled clocks:\n");
-	for (i = 0; i < num_msm_clocks; i++) {
-		clk = msm_clocks[i].clk;
-
-		if (clk && clk->ops->is_enabled && clk->ops->is_enabled(clk)) {
-			pr_info("\t%s\n", clk->dbg_name);
-			cnt++;
-		}
-	}
+	for (i = 0; i < num_msm_clocks; i++)
+		cnt += clock_debug_print_clock(msm_clocks[i].clk);
 
 	if (cnt)
 		pr_info("Enabled clock count: %d\n", cnt);
diff --git a/arch/arm/mach-msm/clock-dummy.c b/arch/arm/mach-msm/clock-dummy.c
index 1798a3c..feef984 100644
--- a/arch/arm/mach-msm/clock-dummy.c
+++ b/arch/arm/mach-msm/clock-dummy.c
@@ -17,17 +17,17 @@
 	return 0;
 }
 
-static int dummy_clk_set_rate(struct clk *clk, unsigned rate)
+static int dummy_clk_set_rate(struct clk *clk, unsigned long rate)
 {
 	return 0;
 }
 
-static int dummy_clk_set_min_rate(struct clk *clk, unsigned rate)
+static int dummy_clk_set_min_rate(struct clk *clk, unsigned long rate)
 {
 	return 0;
 }
 
-static int dummy_clk_set_max_rate(struct clk *clk, unsigned rate)
+static int dummy_clk_set_max_rate(struct clk *clk, unsigned long rate)
 {
 	return 0;
 }
@@ -37,12 +37,12 @@
 	return 0;
 }
 
-static unsigned dummy_clk_get_rate(struct clk *clk)
+static unsigned long dummy_clk_get_rate(struct clk *clk)
 {
 	return 0;
 }
 
-static long dummy_clk_round_rate(struct clk *clk, unsigned rate)
+static long dummy_clk_round_rate(struct clk *clk, unsigned long rate)
 {
 	return rate;
 }
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index ca25802..c1cfb55 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -508,7 +508,7 @@
 }
 
 /* Set a clock to an exact rate. */
-int rcg_clk_set_rate(struct clk *c, unsigned rate)
+int rcg_clk_set_rate(struct clk *c, unsigned long rate)
 {
 	struct rcg_clk *clk = to_rcg_clk(c);
 	struct clk_freq_tbl *nf;
@@ -524,7 +524,7 @@
 }
 
 /* Set a clock to a rate greater than some minimum. */
-int rcg_clk_set_min_rate(struct clk *c, unsigned rate)
+int rcg_clk_set_min_rate(struct clk *c, unsigned long rate)
 {
 	struct rcg_clk *clk = to_rcg_clk(c);
 	struct clk_freq_tbl *nf;
@@ -540,7 +540,7 @@
 }
 
 /* Get the currently-set rate of a clock in Hz. */
-unsigned rcg_clk_get_rate(struct clk *c)
+unsigned long rcg_clk_get_rate(struct clk *c)
 {
 	struct rcg_clk *clk = to_rcg_clk(c);
 	unsigned long flags;
@@ -567,7 +567,7 @@
 }
 
 /* Return a supported rate that's at least the specified rate. */
-long rcg_clk_round_rate(struct clk *c, unsigned rate)
+long rcg_clk_round_rate(struct clk *c, unsigned long rate)
 {
 	struct rcg_clk *clk = to_rcg_clk(c);
 	struct clk_freq_tbl *f;
@@ -673,7 +673,7 @@
 	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
 }
 
-static unsigned pll_vote_clk_get_rate(struct clk *clk)
+static unsigned long pll_vote_clk_get_rate(struct clk *clk)
 {
 	struct pll_vote_clk *pll = to_pll_vote_clk(clk);
 	return pll->rate;
@@ -694,6 +694,7 @@
 struct clk_ops clk_ops_pll_vote = {
 	.enable = pll_vote_clk_enable,
 	.disable = pll_vote_clk_disable,
+	.auto_off = pll_vote_clk_disable,
 	.is_enabled = pll_vote_clk_is_enabled,
 	.get_rate = pll_vote_clk_get_rate,
 	.get_parent = pll_vote_clk_get_parent,
@@ -752,7 +753,7 @@
 	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
 }
 
-static unsigned pll_clk_get_rate(struct clk *clk)
+static unsigned long pll_clk_get_rate(struct clk *clk)
 {
 	struct pll_clk *pll = to_pll_clk(clk);
 	return pll->rate;
@@ -802,6 +803,7 @@
 struct clk_ops clk_ops_pll = {
 	.enable = pll_clk_enable,
 	.disable = pll_clk_disable,
+	.auto_off = pll_clk_disable,
 	.get_rate = pll_clk_get_rate,
 	.get_parent = pll_clk_get_parent,
 	.is_local = local_clk_is_local,
diff --git a/arch/arm/mach-msm/clock-local.h b/arch/arm/mach-msm/clock-local.h
index 9887bb1..16a9955 100644
--- a/arch/arm/mach-msm/clock-local.h
+++ b/arch/arm/mach-msm/clock-local.h
@@ -143,12 +143,12 @@
 
 int rcg_clk_enable(struct clk *clk);
 void rcg_clk_disable(struct clk *clk);
-int rcg_clk_set_rate(struct clk *clk, unsigned rate);
-int rcg_clk_set_min_rate(struct clk *clk, unsigned rate);
-unsigned rcg_clk_get_rate(struct clk *clk);
+int rcg_clk_set_rate(struct clk *clk, unsigned long rate);
+int rcg_clk_set_min_rate(struct clk *clk, unsigned long rate);
+unsigned long rcg_clk_get_rate(struct clk *clk);
 int rcg_clk_list_rate(struct clk *clk, unsigned n);
 int rcg_clk_is_enabled(struct clk *clk);
-long rcg_clk_round_rate(struct clk *clk, unsigned rate);
+long rcg_clk_round_rate(struct clk *clk, unsigned long rate);
 struct clk *rcg_clk_get_parent(struct clk *c);
 int rcg_clk_handoff(struct clk *c);
 
@@ -167,7 +167,7 @@
 	return container_of(clk, struct fixed_clk, c);
 }
 
-static inline unsigned fixed_clk_get_rate(struct clk *clk)
+static inline unsigned long fixed_clk_get_rate(struct clk *clk)
 {
 	struct fixed_clk *f = to_fixed_clk(clk);
 	return f->rate;
diff --git a/arch/arm/mach-msm/clock-pcom.c b/arch/arm/mach-msm/clock-pcom.c
index f7f3666..79fe662 100644
--- a/arch/arm/mach-msm/clock-pcom.c
+++ b/arch/arm/mach-msm/clock-pcom.c
@@ -74,28 +74,29 @@
 	return pc_clk_reset(id, action);
 }
 
-static int pc_clk_set_rate(struct clk *clk, unsigned rate)
+static int pc_clk_set_rate(struct clk *clk, unsigned long rate)
 {
 	/* The rate _might_ be rounded off to the nearest KHz value by the
 	 * remote function. So a return value of 0 doesn't necessarily mean
 	 * that the exact rate was set successfully.
 	 */
+	unsigned r = rate;
 	int id = to_pcom_clk(clk)->id;
-	int rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate);
+	int rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &r);
 	if (rc < 0)
 		return rc;
 	else
 		return (int)id < 0 ? -EINVAL : 0;
 }
 
-static int pc_clk_set_min_rate(struct clk *clk, unsigned rate)
+static int pc_clk_set_min_rate(struct clk *clk, unsigned long rate)
 {
 	int rc;
 	int id = to_pcom_clk(clk)->id;
 	bool ignore_error = (cpu_is_msm7x27() && id == P_EBI1_CLK &&
 				rate >= INT_MAX);
-
-	rc = msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate);
+	unsigned r = rate;
+	rc = msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &r);
 	if (rc < 0)
 		return rc;
 	else if (ignore_error)
@@ -104,10 +105,11 @@
 		return (int)id < 0 ? -EINVAL : 0;
 }
 
-static int pc_clk_set_max_rate(struct clk *clk, unsigned rate)
+static int pc_clk_set_max_rate(struct clk *clk, unsigned long rate)
 {
 	int id = to_pcom_clk(clk)->id;
-	int rc = msm_proc_comm(PCOM_CLKCTL_RPC_MAX_RATE, &id, &rate);
+	unsigned r = rate;
+	int rc = msm_proc_comm(PCOM_CLKCTL_RPC_MAX_RATE, &id, &r);
 	if (rc < 0)
 		return rc;
 	else
@@ -124,17 +126,18 @@
 		return (int)id < 0 ? -EINVAL : 0;
 }
 
-static int pc_clk_set_ext_config(struct clk *clk, unsigned config)
+static int pc_clk_set_ext_config(struct clk *clk, unsigned long config)
 {
 	int id = to_pcom_clk(clk)->id;
-	int rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_EXT_CONFIG, &id, &config);
+	unsigned c = config;
+	int rc = msm_proc_comm(PCOM_CLKCTL_RPC_SET_EXT_CONFIG, &id, &c);
 	if (rc < 0)
 		return rc;
 	else
 		return (int)id < 0 ? -EINVAL : 0;
 }
 
-static unsigned pc_clk_get_rate(struct clk *clk)
+static unsigned long pc_clk_get_rate(struct clk *clk)
 {
 	int id = to_pcom_clk(clk)->id;
 	if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, NULL))
@@ -152,7 +155,7 @@
 		return id;
 }
 
-static long pc_clk_round_rate(struct clk *clk, unsigned rate)
+static long pc_clk_round_rate(struct clk *clk, unsigned long rate)
 {
 
 	/* Not really supported; pc_clk_set_rate() does rounding on it's own. */
diff --git a/arch/arm/mach-msm/clock-rpm.c b/arch/arm/mach-msm/clock-rpm.c
index 2ccebb4..75cba59 100644
--- a/arch/arm/mach-msm/clock-rpm.c
+++ b/arch/arm/mach-msm/clock-rpm.c
@@ -26,8 +26,8 @@
 	struct msm_rpm_iv_pair iv;
 	int rc = 0;
 	struct rpm_clk *r = to_rpm_clk(clk);
-	unsigned this_khz, this_sleep_khz;
-	unsigned peer_khz = 0, peer_sleep_khz = 0;
+	unsigned long this_khz, this_sleep_khz;
+	unsigned long peer_khz = 0, peer_sleep_khz = 0;
 	struct rpm_clk *peer = r->peer;
 
 	spin_lock_irqsave(&rpm_clock_lock, flags);
@@ -78,7 +78,7 @@
 	if (r->last_set_khz) {
 		struct msm_rpm_iv_pair iv;
 		struct rpm_clk *peer = r->peer;
-		unsigned peer_khz = 0, peer_sleep_khz = 0;
+		unsigned long peer_khz = 0, peer_sleep_khz = 0;
 		int rc;
 
 		iv.id = r->rpm_clk_id;
@@ -104,11 +104,11 @@
 	return;
 }
 
-static int rpm_clk_set_min_rate(struct clk *clk, unsigned rate)
+static int rpm_clk_set_min_rate(struct clk *clk, unsigned long rate)
 {
 	unsigned long flags;
 	struct rpm_clk *r = to_rpm_clk(clk);
-	unsigned this_khz, this_sleep_khz;
+	unsigned long this_khz, this_sleep_khz;
 	int rc = 0;
 
 	this_khz = DIV_ROUND_UP(rate, 1000);
@@ -129,7 +129,7 @@
 	if (r->enabled) {
 		struct msm_rpm_iv_pair iv;
 		struct rpm_clk *peer = r->peer;
-		unsigned peer_khz = 0, peer_sleep_khz = 0;
+		unsigned long peer_khz = 0, peer_sleep_khz = 0;
 
 		iv.id = r->rpm_clk_id;
 
@@ -158,7 +158,7 @@
 	return rc;
 }
 
-static unsigned rpm_clk_get_rate(struct clk *clk)
+static unsigned long rpm_clk_get_rate(struct clk *clk)
 {
 	struct rpm_clk *r = to_rpm_clk(clk);
 	struct msm_rpm_iv_pair iv = { r->rpm_status_id };
@@ -175,7 +175,7 @@
 	return !!(rpm_clk_get_rate(clk));
 }
 
-static long rpm_clk_round_rate(struct clk *clk, unsigned rate)
+static long rpm_clk_round_rate(struct clk *clk, unsigned long rate)
 {
 	/* Not supported. */
 	return rate;
diff --git a/arch/arm/mach-msm/clock-voter.c b/arch/arm/mach-msm/clock-voter.c
index e754752..56beca1 100644
--- a/arch/arm/mach-msm/clock-voter.c
+++ b/arch/arm/mach-msm/clock-voter.c
@@ -21,10 +21,10 @@
 static DEFINE_SPINLOCK(voter_clk_lock);
 
 /* Aggregate the rate of clocks that are currently on. */
-static unsigned voter_clk_aggregate_rate(const struct clk *parent)
+static unsigned long voter_clk_aggregate_rate(const struct clk *parent)
 {
 	struct clk *clk;
-	unsigned rate = 0;
+	unsigned long rate = 0;
 
 	list_for_each_entry(clk, &parent->children, siblings) {
 		struct clk_voter *v = to_clk_voter(clk);
@@ -34,13 +34,13 @@
 	return rate;
 }
 
-static int voter_clk_set_rate(struct clk *clk, unsigned rate)
+static int voter_clk_set_rate(struct clk *clk, unsigned long rate)
 {
 	int ret = 0;
 	unsigned long flags;
 	struct clk *clkp;
 	struct clk_voter *clkh, *v = to_clk_voter(clk);
-	unsigned cur_rate, new_rate, other_rate = 0;
+	unsigned long cur_rate, new_rate, other_rate = 0;
 
 	spin_lock_irqsave(&voter_clk_lock, flags);
 
@@ -77,7 +77,7 @@
 {
 	int ret = 0;
 	unsigned long flags;
-	unsigned cur_rate;
+	unsigned long cur_rate;
 	struct clk *parent;
 	struct clk_voter *v = to_clk_voter(clk);
 
@@ -103,10 +103,9 @@
 
 static void voter_clk_disable(struct clk *clk)
 {
-	unsigned long flags;
+	unsigned long flags, cur_rate, new_rate;
 	struct clk *parent;
 	struct clk_voter *v = to_clk_voter(clk);
-	unsigned cur_rate, new_rate;
 
 	spin_lock_irqsave(&voter_clk_lock, flags);
 	parent = v->parent;
@@ -125,10 +124,9 @@
 	spin_unlock_irqrestore(&voter_clk_lock, flags);
 }
 
-static unsigned voter_clk_get_rate(struct clk *clk)
+static unsigned long voter_clk_get_rate(struct clk *clk)
 {
-	unsigned rate;
-	unsigned long flags;
+	unsigned long rate, flags;
 	struct clk_voter *v = to_clk_voter(clk);
 
 	spin_lock_irqsave(&voter_clk_lock, flags);
@@ -144,7 +142,7 @@
 	return v->enabled;
 }
 
-static long voter_clk_round_rate(struct clk *clk, unsigned rate)
+static long voter_clk_round_rate(struct clk *clk, unsigned long rate)
 {
 	struct clk_voter *v = to_clk_voter(clk);
 	return clk_round_rate(v->parent, rate);
diff --git a/arch/arm/mach-msm/clock-voter.h b/arch/arm/mach-msm/clock-voter.h
index 64baf3b..10353d4 100644
--- a/arch/arm/mach-msm/clock-voter.h
+++ b/arch/arm/mach-msm/clock-voter.h
@@ -19,7 +19,7 @@
 
 struct clk_voter {
 	bool enabled;
-	unsigned rate;
+	unsigned long rate;
 	struct clk *parent;
 	struct clk c;
 };
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index de89382..eff85f0 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -133,7 +133,7 @@
 int clk_enable(struct clk *clk)
 {
 	int ret = 0;
-	unsigned long flags, rate;
+	unsigned long flags;
 	struct clk *parent;
 
 	if (!clk)
@@ -142,7 +142,6 @@
 	spin_lock_irqsave(&clk->lock, flags);
 	if (clk->count == 0) {
 		parent = clk_get_parent(clk);
-		rate = clk_get_rate(clk);
 
 		ret = clk_enable(parent);
 		if (ret)
@@ -151,7 +150,7 @@
 		if (ret)
 			goto err_enable_depends;
 
-		ret = vote_rate_vdd(clk, rate);
+		ret = vote_rate_vdd(clk, clk->rate);
 		if (ret)
 			goto err_vote_vdd;
 		if (clk->ops->enable)
@@ -175,7 +174,7 @@
 	return 0;
 
 err_enable_clock:
-	unvote_rate_vdd(clk, rate);
+	unvote_rate_vdd(clk, clk->rate);
 err_vote_vdd:
 	clk_disable(clk->depends);
 err_enable_depends:
@@ -198,11 +197,10 @@
 		goto out;
 	if (clk->count == 1) {
 		struct clk *parent = clk_get_parent(clk);
-		unsigned long rate = clk_get_rate(clk);
 
 		if (clk->ops->disable)
 			clk->ops->disable(clk);
-		unvote_rate_vdd(clk, rate);
+		unvote_rate_vdd(clk, clk->rate);
 		clk_disable(clk->depends);
 		clk_disable(parent);
 	}
@@ -230,29 +228,34 @@
 }
 EXPORT_SYMBOL(clk_get_rate);
 
-int clk_set_rate(struct clk *clk, unsigned long rate)
+static int _clk_set_rate(struct clk *clk, unsigned long rate,
+			 int (*set_fn)(struct clk *, unsigned long))
 {
 	unsigned long start_rate, flags;
 	int rc;
 
-	if (!clk->ops->set_rate)
+	if (!set_fn)
 		return -ENOSYS;
 
 	spin_lock_irqsave(&clk->lock, flags);
 	if (clk->count) {
-		start_rate = clk_get_rate(clk);
+		start_rate = clk->rate;
 		/* Enforce vdd requirements for target frequency. */
 		rc = vote_rate_vdd(clk, rate);
 		if (rc)
 			goto err_vote_vdd;
-		rc = clk->ops->set_rate(clk, rate);
+		rc = set_fn(clk, rate);
 		if (rc)
 			goto err_set_rate;
 		/* Release vdd requirements for starting frequency. */
 		unvote_rate_vdd(clk, start_rate);
 	} else {
-		rc = clk->ops->set_rate(clk, rate);
+		rc = set_fn(clk, rate);
 	}
+
+	if (!rc)
+		clk->rate = rate;
+
 	spin_unlock_irqrestore(&clk->lock, flags);
 	return rc;
 
@@ -262,7 +265,6 @@
 	spin_unlock_irqrestore(&clk->lock, flags);
 	return rc;
 }
-EXPORT_SYMBOL(clk_set_rate);
 
 long clk_round_rate(struct clk *clk, unsigned long rate)
 {
@@ -273,12 +275,15 @@
 }
 EXPORT_SYMBOL(clk_round_rate);
 
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	return _clk_set_rate(clk, rate, clk->ops->set_rate);
+}
+EXPORT_SYMBOL(clk_set_rate);
+
 int clk_set_min_rate(struct clk *clk, unsigned long rate)
 {
-	if (!clk->ops->set_min_rate)
-		return -ENOSYS;
-
-	return clk->ops->set_min_rate(clk, rate);
+	return _clk_set_rate(clk, rate, clk->ops->set_min_rate);
 }
 EXPORT_SYMBOL(clk_set_min_rate);
 
diff --git a/arch/arm/mach-msm/clock.h b/arch/arm/mach-msm/clock.h
index ed5c9c6..81f12c6 100644
--- a/arch/arm/mach-msm/clock.h
+++ b/arch/arm/mach-msm/clock.h
@@ -47,7 +47,7 @@
 	const char *class_name;
 	int (*set_vdd)(struct clk_vdd_class *v_class, int level);
 	int level_votes[MAX_VDD_LEVELS];
-	unsigned cur_level;
+	unsigned long cur_level;
 	spinlock_t lock;
 };
 
@@ -65,14 +65,14 @@
 	void (*auto_off)(struct clk *clk);
 	int (*handoff)(struct clk *clk);
 	int (*reset)(struct clk *clk, enum clk_reset_action action);
-	int (*set_rate)(struct clk *clk, unsigned rate);
-	int (*set_min_rate)(struct clk *clk, unsigned rate);
-	int (*set_max_rate)(struct clk *clk, unsigned rate);
+	int (*set_rate)(struct clk *clk, unsigned long rate);
+	int (*set_min_rate)(struct clk *clk, unsigned long rate);
+	int (*set_max_rate)(struct clk *clk, unsigned long rate);
 	int (*set_flags)(struct clk *clk, unsigned flags);
-	unsigned (*get_rate)(struct clk *clk);
+	unsigned long (*get_rate)(struct clk *clk);
 	int (*list_rate)(struct clk *clk, unsigned n);
 	int (*is_enabled)(struct clk *clk);
-	long (*round_rate)(struct clk *clk, unsigned rate);
+	long (*round_rate)(struct clk *clk, unsigned long rate);
 	int (*set_parent)(struct clk *clk, struct clk *parent);
 	struct clk *(*get_parent)(struct clk *clk);
 	bool (*is_local)(struct clk *clk);
@@ -93,6 +93,7 @@
 	struct clk *depends;
 	struct clk_vdd_class *vdd_class;
 	unsigned long fmax[MAX_VDD_LEVELS];
+	unsigned long rate;
 
 	struct list_head children;
 	struct list_head siblings;
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 35a69df..9b8d5ac 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -71,18 +71,18 @@
 
 static struct resource msm_dmov_resource[] = {
 	{
-		.start = ADM_0_SCSS_0_IRQ,
+		.start = ADM_0_SCSS_1_IRQ,
 		.flags = IORESOURCE_IRQ,
 	},
 	{
-		.start = 0x18300000,
-		.end = 0x18300000 + SZ_1M - 1,
+		.start = 0x18320000,
+		.end = 0x18320000 + SZ_1M - 1,
 		.flags = IORESOURCE_MEM,
 	},
 };
 
 static struct msm_dmov_pdata msm_dmov_pdata = {
-	.sd = 0,
+	.sd = 1,
 	.sd_size = 0x800,
 };
 
@@ -664,8 +664,8 @@
 	CLK_DUMMY("iface_clk",		SDC2_P_CLK,		NULL, OFF),
 	CLK_DUMMY("iface_clk",		SDC3_P_CLK,		NULL, OFF),
 	CLK_DUMMY("iface_clk",		SDC4_P_CLK,		NULL, OFF),
-	CLK_DUMMY("core_clk",		ADM0_CLK,		NULL, OFF),
-	CLK_DUMMY("iface_clk",		ADM0_P_CLK,		NULL, OFF),
+	CLK_DUMMY("core_clk",		ADM0_CLK,	"msm_dmov", OFF),
+	CLK_DUMMY("iface_clk",		ADM0_P_CLK,	"msm_dmov", OFF),
 	CLK_DUMMY("iface_clk",		PMIC_ARB0_P_CLK,	NULL, OFF),
 	CLK_DUMMY("iface_clk",		PMIC_ARB1_P_CLK,	NULL, OFF),
 	CLK_DUMMY("core_clk",		PMIC_SSBI2_CLK,		NULL, OFF),
@@ -760,6 +760,7 @@
 	CLK_DUMMY("bus_clk",		DFAB_SDC4_CLK,		NULL, 0),
 	CLK_DUMMY("dfab_clk",		DFAB_CLK,		NULL, 0),
 	CLK_DUMMY("dma_bam_pclk",	DMA_BAM_P_CLK,		NULL, 0),
+	CLK_DUMMY("mem_clk",		EBI1_ADM_CLK,	  "msm_dmov", 0),
 };
 
 struct clock_init_data apq8064_dummy_clock_init_data __initdata = {
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index ba36f69..b737b116 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -36,6 +36,7 @@
 #include "devices-msm8x60.h"
 #include "footswitch.h"
 #include "msm_watchdog.h"
+#include "rpm_stats.h"
 
 #ifdef CONFIG_MSM_MPM
 #include "mpm.h"
@@ -1134,6 +1135,12 @@
 		.flags  = IORESOURCE_IO,
 	},
 	{
+		.name   = "spi_cs1",
+		.start  = 14,
+		.end    = 14,
+		.flags  = IORESOURCE_IO,
+	},
+	{
 		.name   = "spi_miso",
 		.start  = 7,
 		.end    = 7,
@@ -1962,18 +1969,22 @@
 			{
 				.gpu_freq = 400000000,
 				.bus_freq = 4,
+				.io_fraction = 0,
 			},
 			{
 				.gpu_freq = 300000000,
 				.bus_freq = 3,
+				.io_fraction = 33,
 			},
 			{
 				.gpu_freq = 200000000,
 				.bus_freq = 2,
+				.io_fraction = 100,
 			},
 			{
 				.gpu_freq = 128000000,
 				.bus_freq = 1,
+				.io_fraction = 100,
 			},
 			{
 				.gpu_freq = 27000000,
@@ -2239,6 +2250,18 @@
 	.id     = -1,
 };
 
+static struct msm_rpmstats_platform_data msm_rpm_stat_pdata = {
+	.phys_addr_base = 0x0010D204,
+	.phys_size = SZ_8K,
+};
+
+struct platform_device msm_rpm_stat_device = {
+	.name = "msm_rpm_stat",
+	.id = -1,
+	.dev = {
+		.platform_data = &msm_rpm_stat_pdata,
+	},
+};
 
 struct platform_device msm_bus_sys_fabric = {
 	.name  = "msm_bus_fabric",
diff --git a/arch/arm/mach-msm/devices-9615.c b/arch/arm/mach-msm/devices-9615.c
index 3cf7d48..60fa257 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.c
@@ -332,6 +332,11 @@
 	.id		= -1,
 };
 
+struct platform_device msm_device_bam_dmux = {
+	.name		= "BAM_RMNT",
+	.id		= -1,
+};
+
 #ifdef CONFIG_HW_RANDOM_MSM
 /* PRNG device */
 #define MSM_PRNG_PHYS		0x1A500000
diff --git a/arch/arm/mach-msm/devices-msm8x60.c b/arch/arm/mach-msm/devices-msm8x60.c
index def2558..4458adf 100644
--- a/arch/arm/mach-msm/devices-msm8x60.c
+++ b/arch/arm/mach-msm/devices-msm8x60.c
@@ -657,18 +657,22 @@
 			{
 				.gpu_freq = 266667000,
 				.bus_freq = 4,
+				.io_fraction = 0,
 			},
 			{
 				.gpu_freq = 228571000,
 				.bus_freq = 3,
+				.io_fraction = 33,
 			},
 			{
 				.gpu_freq = 200000000,
 				.bus_freq = 2,
+				.io_fraction = 100,
 			},
 			{
 				.gpu_freq = 177778000,
-				.bus_freq = 1
+				.bus_freq = 1,
+				.io_fraction = 100,
 			},
 			{
 				.gpu_freq = 27000000,
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index c490574..4af3e68 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -191,6 +191,7 @@
 
 extern struct platform_device ion_dev;
 extern struct platform_device msm_rpm_device;
+extern struct platform_device msm_rpm_stat_device;
 extern struct platform_device msm_device_rng;
 
 #if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
diff --git a/arch/arm/mach-msm/include/mach/audio_dma_msm8k.h b/arch/arm/mach-msm/include/mach/audio_dma_msm8k.h
index 5c9bfb5..1970d0b 100644
--- a/arch/arm/mach-msm/include/mach/audio_dma_msm8k.h
+++ b/arch/arm/mach-msm/include/mach/audio_dma_msm8k.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, 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
@@ -202,6 +202,11 @@
 #define LPAIF_DMA_SET_BUFF_CNT(x)	DMA_CTRL_ADDR(x, 0x20)
 #define	LPAIF_DMA_SET_PER_CNT(x)	DMA_CTRL_ADDR(x, 0x24)
 
+#define LPAIF_DMA_PER_CNT_PER_CNT_MASK		0x000FFFFF
+#define LPAIF_DMA_PER_CNT_PER_CNT_SHIFT		0
+#define LPAIF_DMA_PER_CNT_FIFO_WORDCNT_MASK	0x00F00000
+#define LPAIF_DMA_PER_CNT_FIFO_WORDCNT_SHIFT	20
+
 /* channel assignments */
 
 #define DMA_CH_0		0
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index 1b6497d..38c9e85 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -24,6 +24,7 @@
 #include <mach/board.h>
 #include <media/msm_camera.h>
 #include <mach/msm_subsystem_map.h>
+#include <linux/ion.h>
 
 #define CONFIG_MSM_CAMERA_DEBUG
 #ifdef CONFIG_MSM_CAMERA_DEBUG
@@ -474,6 +475,7 @@
 	struct msm_pmem_info info;
 	struct msm_mapped_buffer *msm_buffer;
 	int subsys_id;
+	struct ion_handle *handle;
 };
 
 struct axidata {
@@ -615,6 +617,11 @@
 	MODE_DUAL
 };
 
+struct msm_cam_clk_info {
+	const char *clk_name;
+	long clk_rate;
+};
+
 int msm_camio_enable(struct platform_device *dev);
 int msm_camio_jpeg_clk_enable(void);
 int msm_camio_jpeg_clk_disable(void);
@@ -663,4 +670,7 @@
 void *msm_isp_sync_alloc(int size, gfp_t gfp);
 
 void msm_isp_sync_free(void *ptr);
+
+int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info,
+		struct clk **clk_ptr, int num_clk, int enable);
 #endif
diff --git a/arch/arm/mach-msm/include/mach/iommu_domains.h b/arch/arm/mach-msm/include/mach/iommu_domains.h
index 8ae3b72..28e98de 100644
--- a/arch/arm/mach-msm/include/mach/iommu_domains.h
+++ b/arch/arm/mach-msm/include/mach/iommu_domains.h
@@ -13,26 +13,67 @@
 #ifndef _ARCH_IOMMU_DOMAINS_H
 #define _ARCH_IOMMU_DOMAINS_H
 
-/*
- * Nothing in this file is to be used outside of the iommu wrappers.
- * Do NOT try and use anything here in a driver. Doing so is incorrect.
- */
+enum {
+	GLOBAL_DOMAIN,
+	MAX_DOMAINS
+};
 
-/*
- * These subsytem ids are NOT for public use. Please check the iommu
- * wrapper header for the properly abstracted id to pass in.
- */
+enum {
+	VIDEO_FIRMWARE_POOL,
+	LOW_256MB_POOL,
+	HIGH_POOL,
+};
+
 
 #if defined(CONFIG_MSM_IOMMU)
-extern struct iommu_domain *msm_subsystem_get_domain(int subsys_id);
 
-extern struct mem_pool *msm_subsystem_get_pool(int subsys_id);
+extern struct iommu_domain *msm_get_iommu_domain(int domain_num);
+
+extern unsigned long msm_allocate_iova_address(unsigned int iommu_domain,
+					unsigned int partition_no,
+					unsigned long size,
+					unsigned long align);
+
+extern void msm_free_iova_address(unsigned long iova,
+			unsigned int iommu_domain,
+			unsigned int partition_no,
+			unsigned long size);
+
+extern unsigned long msm_subsystem_get_domain_no(int subsys_id);
+
+extern unsigned long msm_subsystem_get_partition_no(int subsys_id);
+
+extern int msm_use_iommu(void);
 #else
 static inline struct iommu_domain
-	*msm_subsystem_get_domain(int subsys_id) { return NULL; }
+	*msm_get_iommu_domain(int subsys_id) { return NULL; }
 
-static inline struct mem_pool
-	*msm_subsystem_get_pool(int subsys_id) { return NULL; }
+
+
+static inline unsigned long msm_allocate_iova_address(unsigned int iommu_domain,
+					unsigned int partition_no,
+					unsigned long size,
+					unsigned long align) { return 0; }
+
+static inline void msm_free_iova_address(unsigned long iova,
+			unsigned int iommu_domain,
+			unsigned int partition_no,
+			unsigned long size) { return; }
+
+static inline unsigned long msm_subsystem_get_domain_no(int subsys_id)
+{
+	return 0xFFFFFFFF;
+}
+
+static inline unsigned long msm_subsystem_get_partition_no(int subsys_id)
+{
+	return 0xFFFFFFFF;
+}
+
+static inline int msm_use_iommu(void)
+{
+	return 0;
+}
 #endif
 
 #endif
diff --git a/arch/arm/mach-msm/include/mach/msm72k_otg.h b/arch/arm/mach-msm/include/mach/msm72k_otg.h
index 43f487a..4509dad 100644
--- a/arch/arm/mach-msm/include/mach/msm72k_otg.h
+++ b/arch/arm/mach-msm/include/mach/msm72k_otg.h
@@ -25,6 +25,7 @@
 
 #define OTGSC_BSVIE            (1 << 27)
 #define OTGSC_IDIE             (1 << 24)
+#define OTGSC_IDPU             (1 << 5)
 #define OTGSC_BSVIS            (1 << 19)
 #define OTGSC_ID               (1 << 8)
 #define OTGSC_IDIS             (1 << 16)
@@ -148,7 +149,6 @@
 	struct wake_lock wlock;
 	unsigned long b_last_se0_sess; /* SRP initial condition check */
 	unsigned long inputs;
-	int pmic_id_status;
 	unsigned long tmouts;
 	u8 active_tmout;
 	struct hrtimer timer;
diff --git a/arch/arm/mach-msm/include/mach/msm_hdmi_audio.h b/arch/arm/mach-msm/include/mach/msm_hdmi_audio.h
index 97dad67..3965a75 100644
--- a/arch/arm/mach-msm/include/mach/msm_hdmi_audio.h
+++ b/arch/arm/mach-msm/include/mach/msm_hdmi_audio.h
@@ -14,5 +14,6 @@
 #define __MSM_HDMI_AUDIO_H
 
 int hdmi_audio_enable(bool on , u32 fifo_water_mark);
+int hdmi_audio_packet_enable(bool on);
 
 #endif /* __MSM_HDMI_AUDIO_H*/
diff --git a/arch/arm/mach-msm/include/mach/msm_hsusb.h b/arch/arm/mach-msm/include/mach/msm_hsusb.h
index 26f1cdd..3e8ab55 100644
--- a/arch/arm/mach-msm/include/mach/msm_hsusb.h
+++ b/arch/arm/mach-msm/include/mach/msm_hsusb.h
@@ -158,6 +158,7 @@
 	/* pmic notfications apis */
 	int (*pmic_vbus_notif_init) (void (*callback)(int online), int init);
 	int (*pmic_id_notif_init) (void (*callback)(int online), int init);
+	int (*phy_id_setup_init) (int init);
 	int (*pmic_register_vbus_sn) (void (*callback)(int online));
 	void (*pmic_unregister_vbus_sn) (void (*callback)(int online));
 	int (*pmic_enable_ldo) (int);
diff --git a/arch/arm/mach-msm/include/mach/msm_smsm.h b/arch/arm/mach-msm/include/mach/msm_smsm.h
index 4641479..0c2cd4b 100644
--- a/arch/arm/mach-msm/include/mach/msm_smsm.h
+++ b/arch/arm/mach-msm/include/mach/msm_smsm.h
@@ -82,6 +82,8 @@
 #define SMSM_WKUP_REASON_TIMER	0x00000008
 #define SMSM_WKUP_REASON_ALARM	0x00000010
 #define SMSM_WKUP_REASON_RESET	0x00000020
+#define SMSM_A2_FORCE_SHUTDOWN 0x00002000
+#define SMSM_A2_RESET_BAM      0x00004000
 
 #define SMSM_VENDOR             0x00020000
 
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/apr.h b/arch/arm/mach-msm/include/mach/qdsp6v2/apr.h
index 8309953..62d7a33 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/apr.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/apr.h
@@ -76,7 +76,8 @@
 #define APR_SVC_ADSP_MVM	0x09
 #define APR_SVC_ADSP_CVS	0x0A
 #define APR_SVC_ADSP_CVP	0x0B
-#define APR_SVC_MAX		0x0C
+#define APR_SVC_USM		0x0C
+#define APR_SVC_MAX		0x0D
 
 /* Modem Service IDs */
 #define APR_SVC_MVS		0x3
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us.h b/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us.h
new file mode 100644
index 0000000..444d7ad
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us.h
@@ -0,0 +1,156 @@
+/* Copyright (c) 2011, 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
+ * 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 __APR_US_H__
+#define __APR_US_H__
+
+#include <mach/qdsp6v2/apr.h>
+
+/* ======================================================================= */
+/*  Session Level commands */
+#define USM_SESSION_CMD_MEMORY_MAP			0x00012304
+struct usm_stream_cmd_memory_map {
+	struct apr_hdr	hdr;
+	u32		buf_add;
+	u32		buf_size;
+	u16		mempool_id;
+	u16		reserved;
+} __packed;
+
+#define USM_SESSION_CMD_MEMORY_UNMAP			0x00012305
+struct usm_stream_cmd_memory_unmap {
+	struct apr_hdr  hdr;
+	u32             buf_add;
+} __packed;
+
+#define USM_SESSION_CMD_RUN				0x00012306
+struct usm_stream_cmd_run {
+	struct apr_hdr hdr;
+	u32            flags;
+	u32            msw_ts;
+	u32            lsw_ts;
+} __packed;
+
+/* Stream level commands */
+#define USM_STREAM_CMD_OPEN_READ			0x00012309
+struct usm_stream_cmd_open_read {
+	struct apr_hdr hdr;
+	u32            uMode;
+	u32            src_endpoint;
+	u32            pre_proc_top;
+	u32            format;
+} __packed;
+
+#define USM_STREAM_CMD_OPEN_WRITE			0x00011271
+struct usm_stream_cmd_open_write {
+	struct apr_hdr hdr;
+	u32            format;
+} __packed;
+
+
+#define USM_STREAM_CMD_CLOSE				0x0001230A
+
+/* Encoder configuration definitions */
+#define USM_STREAM_CMD_SET_ENC_PARAM			0x0001230B
+/* Decoder configuration definitions */
+#define USM_DATA_CMD_MEDIA_FORMAT_UPDATE		0x00011272
+
+/* Encoder/decoder configuration block */
+#define USM_PARAM_ID_ENCDEC_ENC_CFG_BLK			0x0001230D
+
+/* Parameter structures used in  USM_STREAM_CMD_SET_ENCDEC_PARAM command */
+/* common declarations */
+struct usm_cfg_common {
+	u16 ch_cfg;
+	u16 bits_per_sample;
+	u32 sample_rate;
+	u32 dev_id;
+	u32 data_map;
+} __packed;
+
+/* Max number of static located transparent data (bytes) */
+#define USM_MAX_CFG_DATA_SIZE 20
+struct usm_encode_cfg_blk {
+	u32 frames_per_buf;
+	u32 format_id;
+	/* <cfg_size> = sizeof(usm_cfg_common)+|tarnsp_data| */
+	u32 cfg_size;
+	struct usm_cfg_common cfg_common;
+	/* Transparent configuration data for specific encoder */
+	u8  transp_data[USM_MAX_CFG_DATA_SIZE];
+} __packed;
+
+struct usm_stream_cmd_encdec_cfg_blk {
+	struct apr_hdr hdr;
+	u32 param_id;
+	u32 param_size;
+	struct usm_encode_cfg_blk enc_blk;
+} __packed;
+
+struct us_encdec_cfg {
+	u32 format_id;
+	struct usm_cfg_common cfg_common;
+	u16 params_size;
+	u8 *params;
+} __packed;
+
+struct usm_stream_media_format_update {
+	struct apr_hdr hdr;
+	u32 format_id;
+	/* <cfg_size> = sizeof(usm_cfg_common)+|tarnsp_data| */
+	u32 cfg_size;
+	struct usm_cfg_common cfg_common;
+	/* Transparent configuration data for specific encoder */
+	u8  transp_data[USM_MAX_CFG_DATA_SIZE];
+} __packed;
+
+
+#define USM_DATA_CMD_READ				0x0001230E
+struct usm_stream_cmd_read {
+	struct apr_hdr  hdr;
+	u32                 buf_add;
+	u32                 buf_size;
+	u32                 uid;
+	u32                 counter;
+} __packed;
+
+#define USM_DATA_EVENT_READ_DONE			0x0001230F
+struct usm_data_event_read_done {
+	u32            status;
+	u32            buffer_add;
+	u32            enc_frame_size;
+	u32            offset;
+	u32            msw_ts;
+	u32            lsw_ts;
+	u32            flags;
+	u32            num_frames;
+	u32            id;
+} __packed;
+
+#define USM_DATA_CMD_WRITE				0x00011273
+struct usm_stream_cmd_write {
+	struct apr_hdr hdr;
+	u32 buf_add;
+	u32 buf_size;
+	u32 uid;
+	u32 msw_ts;
+	u32 lsw_ts;
+	u32 flags;
+} __packed;
+
+#define USM_DATA_EVENT_WRITE_DONE			0x00011274
+struct usm_data_event_write_done {
+	u32 buf_add;
+	u32 status;
+} __packed;
+
+#endif /* __APR_US_H__ */
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h b/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h
index fb6e22e..1f8ce68 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/q6voice.h
@@ -523,6 +523,10 @@
 /* Media types */
 #define VSS_MEDIA_ID_EVRC_MODEM		0x00010FC2
 /* 80-VF690-47 CDMA enhanced variable rate vocoder modem format. */
+#define VSS_MEDIA_ID_4GV_NB_MODEM  0x00010FC3
+/* 4GV Narrowband modem format */
+#define VSS_MEDIA_ID_4GV_WB_MODEM  0x00010FC4
+/* 4GV Wideband modem format */
 #define VSS_MEDIA_ID_AMR_NB_MODEM	0x00010FC6
 /* 80-VF690-47 UMTS AMR-NB vocoder modem format. */
 #define VSS_MEDIA_ID_AMR_WB_MODEM	0x00010FC7
@@ -652,12 +656,17 @@
 			 uint32_t *pkt_len,
 			 void *private_data);
 
+struct q_min_max_rate {
+	uint32_t min_rate;
+	uint32_t max_rate;
+};
 
 struct mvs_driver_info {
 	uint32_t media_type;
 	uint32_t rate;
 	uint32_t network_type;
 	uint32_t dtx_mode;
+	struct q_min_max_rate q_min_max_rate;
 	ul_cb_fn ul_cb;
 	dl_cb_fn dl_cb;
 	void *private_data;
@@ -750,7 +759,8 @@
 void voice_config_vocoder(uint32_t media_type,
 			  uint32_t rate,
 			  uint32_t network_type,
-			  uint32_t dtx_mode);
+			  uint32_t dtx_mode,
+			  struct q_min_max_rate q_min_max_rate);
 
 int voice_start_record(uint32_t rec_mode, uint32_t set);
 
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/usf.h b/arch/arm/mach-msm/include/mach/qdsp6v2/usf.h
new file mode 100644
index 0000000..346dc0d
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/usf.h
@@ -0,0 +1,185 @@
+/* Copyright (c) 2011, 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
+ * 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 __USF_H__
+#define __USF_H__
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define USF_IOCTL_MAGIC 'U'
+
+#define US_SET_TX_INFO   _IOW(USF_IOCTL_MAGIC, 0, \
+				struct us_tx_info_type)
+#define US_START_TX      _IO(USF_IOCTL_MAGIC, 1)
+#define US_GET_TX_UPDATE _IOWR(USF_IOCTL_MAGIC, 2, \
+				struct us_tx_update_info_type)
+#define US_SET_RX_INFO   _IOW(USF_IOCTL_MAGIC, 3, \
+				struct us_rx_info_type)
+#define US_SET_RX_UPDATE _IOWR(USF_IOCTL_MAGIC, 4, \
+				struct us_rx_update_info_type)
+#define US_START_RX      _IO(USF_IOCTL_MAGIC, 5)
+
+#define US_STOP_TX      _IO(USF_IOCTL_MAGIC, 6)
+#define US_STOP_RX      _IO(USF_IOCTL_MAGIC, 7)
+
+
+/* Encoder (TX), decoder (RX) supported US data formats */
+#define USF_POINT_EPOS_FORMAT	0
+#define USF_RAW_FORMAT		    1
+
+/* Types of events, produced by the calculators */
+#define USF_TSC_EVENT 1
+#define USF_MOUSE_EVENT 2
+#define USF_KEYBOARD_EVENT 4
+#define USF_ALL_EVENTS (USF_TSC_EVENT | USF_MOUSE_EVENT | USF_KEYBOARD_EVENT)
+
+/* Max size of the client name */
+#define USF_MAX_CLIENT_NAME_SIZE	20
+/* Info structure common for TX and RX */
+struct us_xx_info_type {
+/* Input:  general info */
+/* Name of the client - event calculator */
+	const char *client_name;
+/* Selected device identification, accepted in the kernel's CAD */
+	uint32_t dev_id;
+/* 0 - point_epos type; (e.g. 1 - gr_mmrd) */
+	uint32_t stream_format;
+/* Required sample rate in Hz */
+	uint32_t sample_rate;
+/* Size of a buffer (bytes) for US data transfer between the module and USF */
+	uint32_t buf_size;
+/* Number of the buffers for the US data transfer */
+	uint16_t buf_num;
+/* Number of the microphones (TX) or speakers(RX) */
+	uint16_t port_cnt;
+/* Microphones(TX) or speakers(RX) indexes in their enumeration */
+	uint8_t  port_id[4];
+/* Bits per sample 16 or 32 */
+	uint16_t bits_per_sample;
+/* Input:  Transparent info for encoder in the LPASS */
+/* Parameters data size in bytes */
+	uint16_t params_data_size;
+/* Pointer to the parameters */
+	uint8_t *params_data;
+};
+
+struct us_input_info_type {
+	/* Touch screen dimensions: min & max;for input module */
+	int tsc_x_dim[2];
+	int tsc_y_dim[2];
+    /* Touch screen fuzz; for input module */
+	int tsc_x_fuzz;
+	int tsc_y_fuzz;
+	/* Touch screen pressure limits: min & max; for input module */
+	int tsc_pressure[2];
+	/* Bitmap of types of events (USF_X_EVENT), produced by calculator */
+	uint16_t event_types;
+};
+
+struct us_tx_info_type {
+	/* Common info */
+	struct us_xx_info_type us_xx_info;
+	/* Info specific for TX*/
+	struct us_input_info_type input_info;
+};
+
+struct us_rx_info_type {
+	/* Common info */
+	struct us_xx_info_type us_xx_info;
+	/* Info specific for RX*/
+};
+
+
+#define	USF_PIX_COORDINATE  0 /* unit is pixel */
+#define	USF_CMM_COORDINATE  1 /* unit is 0.01 mm */
+struct point_event_type {
+/* Pen coordinates (x, y) in units, defined by <coordinates_type>  */
+	int coordinates[2];
+/* {x;y}  in degrees [-90; 90] */
+	uint32_t inclinations[2];
+/* [0-1023] (10bits); 0 - pen up */
+	uint32_t pressure;
+/* 0 - mapped in the display pixel. 1 - raw in 0.01 mm (only for log); */
+	uint8_t coordinates_type;
+};
+
+/* Mouse buttons, supported by USF */
+#define USF_BUTTON_LEFT_MASK   1
+#define USF_BUTTON_MIDDLE_MASK 2
+#define USF_BUTTON_RIGHT_MASK  4
+struct mouse_event_type {
+/* The mouse relative movement (dX, dY, dZ) */
+	int rels[3];
+/* Bitmap of mouse buttons states: 1 - down, 0 - up; */
+	uint16_t buttons_states;
+};
+
+struct key_event_type {
+/*  Calculated MS key- see input.h. */
+	uint32_t key;
+/* Keyboard's key state: 1 - down, 0 - up; */
+	uint8_t key_state;
+};
+
+struct usf_event_type {
+/* Event sequence number */
+	uint32_t seq_num;
+/* Event generation system time */
+	uint32_t timestamp;
+/* Destination input event type (e.g. touch screen, mouse, key) */
+	uint16_t event_type;
+	union {
+		struct point_event_type point_event;
+		struct mouse_event_type mouse_event;
+		struct key_event_type   key_event;
+	} event_data;
+};
+
+struct us_tx_update_info_type {
+/* Input  general: */
+/* Number of calculated events */
+	uint16_t event_counter;
+/* Calculated events or NULL */
+	struct usf_event_type *event;
+/* Pointer (read index) to the end of available region */
+/* in the shared US data memory */
+	uint32_t free_region;
+/* Input  transparent data: */
+/* Parameters size */
+	uint16_t params_data_size;
+/* Pointer to the parameters */
+	uint8_t *params_data;
+/* Output parameters: */
+/* Pointer (write index) to the end of ready US data region */
+/* in the shared memory */
+	uint32_t ready_region;
+};
+
+struct us_rx_update_info_type {
+/* Input  general: */
+/* Pointer (write index) to the end of ready US data region */
+/* in the shared memory */
+	uint32_t ready_region;
+/* Input  transparent data: */
+/* Parameters size */
+	uint16_t params_data_size;
+/* pPointer to the parameters */
+	uint8_t *params_data;
+/* Output parameters: */
+/* Pointer (read index) to the end of available region */
+/* in the shared US data memory */
+	uint32_t free_region;
+};
+
+#endif /* __USF_H__ */
diff --git a/arch/arm/mach-msm/include/mach/socinfo.h b/arch/arm/mach-msm/include/mach/socinfo.h
index dbde068..fba6efe2 100644
--- a/arch/arm/mach-msm/include/mach/socinfo.h
+++ b/arch/arm/mach-msm/include/mach/socinfo.h
@@ -16,6 +16,9 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/of_fdt.h>
+#include <linux/of.h>
 
 #include <asm/cputype.h>
 #include <asm/mach-types.h>
@@ -28,6 +31,16 @@
 #define SOCINFO_VERSION_MAJOR(ver) ((ver & 0xffff0000) >> 16)
 #define SOCINFO_VERSION_MINOR(ver) (ver & 0x0000ffff)
 
+#ifdef CONFIG_OF
+#define early_machine_is_copper()	\
+	of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,msmcopper")
+#define machine_is_copper()		\
+	of_machine_is_compatible("qcom,msmcopper")
+#else
+#define early_machine_is_copper()	0
+#define machine_is_copper()		0
+#endif
+
 enum msm_cpu {
 	MSM_CPU_UNKNOWN = 0,
 	MSM_CPU_7X01,
@@ -47,6 +60,7 @@
 	MSM_CPU_8930,
 	MSM_CPU_7X27AA,
 	MSM_CPU_9615,
+	MSM_CPU_COPPER,
 };
 
 enum msm_cpu socinfo_get_msm_cpu(void);
diff --git a/arch/arm/mach-msm/iommu_domains.c b/arch/arm/mach-msm/iommu_domains.c
index 290ba33..e849cdb 100644
--- a/arch/arm/mach-msm/iommu_domains.c
+++ b/arch/arm/mach-msm/iommu_domains.c
@@ -18,24 +18,23 @@
 #include <linux/init.h>
 #include <mach/iommu.h>
 #include <mach/iommu_domains.h>
+#include <mach/socinfo.h>
 
 struct msm_iommu_domain {
-	int domain_idx;
-	int iova_pool_idx;
+	/* iommu domain to map in */
+	struct iommu_domain *domain;
+	/* total number of allocations from this domain */
+	atomic_t allocation_cnt;
+	/* number of iova pools */
+	int npools;
+	/*
+	 * array of gen_pools for allocating iovas.
+	 * behavior is undefined if these overlap
+	 */
+	struct mem_pool *iova_pools;
+
 };
 
-enum {
-	GLOBAL_DOMAIN,
-	VIDEO_DOMAIN,
-	EMPTY_DOMAIN,
-	MAX_DOMAINS
-};
-
-enum {
-	GLOBAL_MEMORY_POOL,
-	VIDEO_FIRMWARE_POOL,
-	VIDEO_ALLOC_POOL,
-};
 
 struct {
 	char *name;
@@ -114,114 +113,175 @@
 	/* Video */
 	{
 		.name = "vcodec_a_mm1",
-		.domain = VIDEO_DOMAIN,
+		.domain = GLOBAL_DOMAIN,
 	},
 	/* Video */
 	{
 		.name = "vcodec_b_mm2",
-		.domain = VIDEO_DOMAIN,
+		.domain = GLOBAL_DOMAIN,
 	},
 	/* Video */
 	{
 		.name = "vcodec_a_stream",
-		.domain = VIDEO_DOMAIN,
+		.domain = GLOBAL_DOMAIN,
 	},
 };
 
-static struct iommu_domain *msm_iommu_domains[MAX_DOMAINS];
-
-static struct mem_pool msm_iommu_iova_pools[] = {
-	[GLOBAL_MEMORY_POOL] = {
-		.paddr	= SZ_4K,
-		.size	= SZ_2G - SZ_4K,
-	},
+static struct mem_pool global_pools[] =  {
+	[VIDEO_FIRMWARE_POOL] =
+	/* Low addresses, intended for video firmware */
+		{
+			.paddr	= SZ_128K,
+			.size	= SZ_16M - SZ_128K,
+		},
+	[LOW_256MB_POOL] =
 	/*
-	 * The video hardware has several constraints:
-	 * 1) The start address for firmware must be 128K aligned
-	 * 2) The video firmware must exist at a lower address than
-	 *	all other video allocations
-	 * 3) Video allocations cannot be more than 256MB away from the
-	 *	firmware
-	 *
-	 * Splitting the video pools makes sure that firmware will
-	 * always be lower than regular allocations and the maximum
-	 * size of 256MB will be enforced.
+	 * Video can only access first 256MB of memory
+	 * dedicated pool for such allocations
 	 */
-	[VIDEO_FIRMWARE_POOL] = {
-		.paddr	= SZ_128K,
-		.size	= SZ_16M - SZ_128K,
-	},
-	[VIDEO_ALLOC_POOL] = {
-		.paddr	= SZ_16M,
-		.size	= SZ_256M - SZ_16M - SZ_128K,
+		{
+			.paddr	= SZ_16M,
+			.size	= SZ_256M - SZ_16M,
+		},
+	[HIGH_POOL] =
+	/* Remaining address space up to 2G */
+		{
+			.paddr	= SZ_256M,
+			.size	= SZ_2G - SZ_256M,
+		}
+};
+
+
+static struct msm_iommu_domain msm_iommu_domains[] = {
+	[GLOBAL_DOMAIN] = {
+		.iova_pools = global_pools,
+		.npools = ARRAY_SIZE(global_pools),
 	}
 };
 
-static struct msm_iommu_domain msm_iommu_subsystems[] = {
-	[MSM_SUBSYSTEM_VIDEO]	= {
-		.domain_idx	= VIDEO_DOMAIN,
-		.iova_pool_idx	= VIDEO_ALLOC_POOL,
-	},
-	[MSM_SUBSYSTEM_VIDEO_FWARE]	= {
-		.domain_idx	= VIDEO_DOMAIN,
-		.iova_pool_idx	= VIDEO_FIRMWARE_POOL,
-	},
-	[MSM_SUBSYSTEM_CAMERA]	= {
-		.domain_idx	= GLOBAL_DOMAIN,
-		.iova_pool_idx	= GLOBAL_MEMORY_POOL,
-	},
-	[MSM_SUBSYSTEM_DISPLAY]	= {
-		.domain_idx	= GLOBAL_DOMAIN,
-		.iova_pool_idx	= GLOBAL_MEMORY_POOL,
-	},
-	[MSM_SUBSYSTEM_ROTATOR]	= {
-		.domain_idx	= GLOBAL_DOMAIN,
-		.iova_pool_idx	= GLOBAL_MEMORY_POOL,
-	},
-};
-
-struct iommu_domain *msm_subsystem_get_domain(int subsys_id)
+struct iommu_domain *msm_get_iommu_domain(int domain_num)
 {
-	int id = msm_iommu_subsystems[subsys_id].domain_idx;
-
-	return msm_iommu_domains[id];
+	if (domain_num >= 0 && domain_num < MAX_DOMAINS)
+		return msm_iommu_domains[domain_num].domain;
+	else
+		return NULL;
 }
 
-struct mem_pool *msm_subsystem_get_pool(int subsys_id)
+unsigned long msm_subsystem_get_domain_no(int subsys_id)
 {
-	int id = msm_iommu_subsystems[subsys_id].iova_pool_idx;
+	return GLOBAL_DOMAIN;
+}
 
-	return &msm_iommu_iova_pools[id];
+unsigned long msm_subsystem_get_partition_no(int subsys_id)
+{
+	switch (subsys_id) {
+	case MSM_SUBSYSTEM_VIDEO_FWARE:
+		return VIDEO_FIRMWARE_POOL;
+	case MSM_SUBSYSTEM_VIDEO:
+		return LOW_256MB_POOL;
+	case MSM_SUBSYSTEM_CAMERA:
+	case MSM_SUBSYSTEM_DISPLAY:
+	case MSM_SUBSYSTEM_ROTATOR:
+		return HIGH_POOL;
+	default:
+		return 0xFFFFFFFF;
+	}
+}
+
+unsigned long msm_allocate_iova_address(unsigned int iommu_domain,
+					unsigned int partition_no,
+					unsigned long size,
+					unsigned long align)
+{
+	struct mem_pool *pool;
+	unsigned long iova;
+
+	if (iommu_domain >= MAX_DOMAINS)
+		return 0;
+
+	if (partition_no >= msm_iommu_domains[iommu_domain].npools)
+		return 0;
+
+	pool = &msm_iommu_domains[iommu_domain].iova_pools[partition_no];
+
+	if (!pool->gpool)
+		return 0;
+
+	iova = gen_pool_alloc_aligned(pool->gpool, size, ilog2(align));
+	if (iova)
+		pool->free -= size;
+
+	return iova;
+}
+
+void msm_free_iova_address(unsigned long iova,
+			   unsigned int iommu_domain,
+			   unsigned int partition_no,
+			   unsigned long size)
+{
+	struct mem_pool *pool;
+
+	if (iommu_domain >= MAX_DOMAINS) {
+		WARN(1, "Invalid domain %d\n", iommu_domain);
+		return;
+	}
+
+	if (partition_no >= msm_iommu_domains[iommu_domain].npools) {
+		WARN(1, "Invalid partition %d for domain %d\n",
+			partition_no, iommu_domain);
+		return;
+	}
+
+	pool = &msm_iommu_domains[iommu_domain].iova_pools[partition_no];
+
+	if (!pool)
+		return;
+
+	pool->free += size;
+	gen_pool_free(pool->gpool, iova, size);
+}
+
+int msm_use_iommu()
+{
+	/*
+	 * For now, just detect if the iommu is attached.
+	 */
+	return iommu_found();
 }
 
 static int __init msm_subsystem_iommu_init(void)
 {
-	int i;
+	int i, j;
 
-	for (i = 0; i < (ARRAY_SIZE(msm_iommu_domains) - 1); i++)
-		msm_iommu_domains[i] = iommu_domain_alloc(0);
-
-	for (i = 0; i < ARRAY_SIZE(msm_iommu_iova_pools); i++) {
-		mutex_init(&msm_iommu_iova_pools[i].pool_mutex);
-		msm_iommu_iova_pools[i].gpool = gen_pool_create(PAGE_SHIFT, -1);
-
-		if (!msm_iommu_iova_pools[i].gpool) {
-			pr_err("%s: could not allocate iova pool. iommu"
-				" programming will not work with iova space"
-				" %d\n", __func__, i);
+	for (i = 0; i < ARRAY_SIZE(msm_iommu_domains); i++) {
+		msm_iommu_domains[i].domain = iommu_domain_alloc(0);
+		if (!msm_iommu_domains[i].domain)
 			continue;
-		}
 
-		if (gen_pool_add(msm_iommu_iova_pools[i].gpool,
-				msm_iommu_iova_pools[i].paddr,
-				msm_iommu_iova_pools[i].size,
-				-1)) {
-			pr_err("%s: could not add memory to iova pool. iommu"
-				" programming will not work with iova space"
-				" %d\n", __func__, i);
-			gen_pool_destroy(msm_iommu_iova_pools[i].gpool);
-			msm_iommu_iova_pools[i].gpool = NULL;
-			continue;
+		for (j = 0; j < msm_iommu_domains[i].npools; j++) {
+			struct mem_pool *pool = &msm_iommu_domains[i].
+							iova_pools[j];
+			mutex_init(&pool->pool_mutex);
+			pool->gpool = gen_pool_create(PAGE_SHIFT, -1);
+
+			if (!pool->gpool) {
+				pr_err("%s: domain %d: could not allocate iova"
+					" pool. iommu programming will not work"
+					" with iova space %d\n", __func__,
+					i, j);
+				continue;
+			}
+
+			if (gen_pool_add(pool->gpool, pool->paddr, pool->size,
+						-1)) {
+				pr_err("%s: domain %d: could not add memory to"
+					" iova pool. iommu programming will not"
+					" work with iova space %d\n", __func__,
+					i, j);
+				gen_pool_destroy(pool->gpool);
+				pool->gpool = NULL;
+				continue;
+			}
 		}
 	}
 
@@ -235,15 +295,15 @@
 
 		domain_idx = msm_iommu_ctx_names[i].domain;
 
-		if (!msm_iommu_domains[domain_idx])
+		if (!msm_iommu_domains[domain_idx].domain)
 			continue;
 
-		if (iommu_attach_device(msm_iommu_domains[domain_idx], ctx)) {
-			pr_err("%s: could not attach domain %d to context %s."
+		if (iommu_attach_device(msm_iommu_domains[domain_idx].domain,
+					ctx)) {
+			WARN(1, "%s: could not attach domain %d to context %s."
 				" iommu programming will not occur.\n",
 				__func__, domain_idx,
 				msm_iommu_ctx_names[i].name);
-			msm_iommu_subsystems[i].domain_idx = EMPTY_DOMAIN;
 			continue;
 		}
 	}
diff --git a/arch/arm/mach-msm/mdm.c b/arch/arm/mach-msm/mdm.c
index 9fa1a4a..01cc48a 100644
--- a/arch/arm/mach-msm/mdm.c
+++ b/arch/arm/mach-msm/mdm.c
@@ -119,6 +119,9 @@
 
 	CHARM_DBG("%s: setting AP2MDM_ERRFATAL high for a non graceful reset\n",
 			 __func__);
+	if (get_restart_level() == RESET_SOC)
+		pm8058_stay_on();
+
 	charm_disable_irqs();
 	gpio_set_value(AP2MDM_ERRFATAL, 1);
 	gpio_set_value(AP2MDM_WAKEUP, 1);
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_arb.c b/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
index 56bc71d..7b9a16e 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
@@ -412,8 +412,16 @@
 	struct msm_bus_client *client = NULL;
 	int i;
 	int src, dest, nfab;
+	struct msm_bus_fabric_device *deffab;
+
+	deffab = msm_bus_get_fabric_device(MSM_BUS_FAB_DEFAULT);
+	if (!deffab) {
+		MSM_BUS_ERR("Error finding default fabric\n");
+		return -ENXIO;
+	}
+
 	nfab = msm_bus_get_num_fab();
-	if (nfab < NUM_FAB) {
+	if (nfab < deffab->board_algo->board_nfab) {
 		MSM_BUS_ERR("Can't register client!\n"
 				"Num of fabrics up: %d\n",
 				nfab);
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_8660.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_8660.c
index fde2322..ff2876c 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_8660.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_8660.c
@@ -23,6 +23,7 @@
 
 #define NMASTERS 39
 #define NSLAVES 67
+#define NFAB_8660 5
 
 enum msm_bus_fabric_tiered_slave_type {
 	MSM_BUS_SYSTEM_TIERED_SLAVE_FAB_APPSS = 1,
@@ -830,6 +831,7 @@
 }
 
 static struct msm_bus_board_algorithm msm_bus_board_algo = {
+	.board_nfab = NFAB_8660,
 	.get_iid = msm_bus_board_8660_get_iid,
 	.assign_iids = msm_bus_board_assign_iids,
 };
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c
index 47f3c81..1dda082 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c
@@ -23,6 +23,7 @@
 
 #define NMASTERS 45
 #define NSLAVES 75
+#define NFAB_8960 5
 
 enum msm_bus_fabric_tiered_slave_type {
 	MSM_BUS_SYSTEM_TIERED_SLAVE_FAB_APPSS_0 = 1,
@@ -863,6 +864,7 @@
 }
 
 static struct msm_bus_board_algorithm msm_bus_board_algo = {
+	.board_nfab = NFAB_8960,
 	.get_iid = msm_bus_board_8960_get_iid,
 	.assign_iids = msm_bus_board_assign_iids,
 };
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_core.h b/arch/arm/mach-msm/msm_bus/msm_bus_core.h
index 8a46026..c4c01e8 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_core.h
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_core.h
@@ -134,6 +134,7 @@
 };
 
 struct msm_bus_board_algorithm {
+	const int board_nfab;
 	void (*assign_iids)(struct msm_bus_fabric_registration *fabreg,
 		int fabid);
 	int (*get_iid)(int id);
diff --git a/arch/arm/mach-msm/qdsp6v2/Makefile b/arch/arm/mach-msm/qdsp6v2/Makefile
index 5e88927..7759c74 100644
--- a/arch/arm/mach-msm/qdsp6v2/Makefile
+++ b/arch/arm/mach-msm/qdsp6v2/Makefile
@@ -16,3 +16,4 @@
 obj-y += audio_acdb.o
 obj-y += aac_in.o qcelp_in.o evrc_in.o amrnb_in.o audio_utils.o
 obj-y += audio_wma.o audio_wmapro.o audio_aac.o audio_multi_aac.o audio_utils_aio.o
+obj-$(CONFIG_MSM_ULTRASOUND) += ultrasound/
diff --git a/arch/arm/mach-msm/qdsp6v2/apr.c b/arch/arm/mach-msm/qdsp6v2/apr.c
index c4eb205..78f6519 100644
--- a/arch/arm/mach-msm/qdsp6v2/apr.c
+++ b/arch/arm/mach-msm/qdsp6v2/apr.c
@@ -191,6 +191,7 @@
 		if (svc == APR_SVC_AFE || svc == APR_SVC_ASM ||
 			svc == APR_SVC_VSM || svc == APR_SVC_VPM ||
 			svc == APR_SVC_ADM || svc == APR_SVC_ADSP_CORE ||
+			svc == APR_SVC_USM ||
 			svc == APR_SVC_TEST_CLIENT || svc == APR_SVC_ADSP_MVM ||
 			svc == APR_SVC_ADSP_CVS || svc == APR_SVC_ADSP_CVP)
 			clnt = APR_CLIENT_AUDIO;
@@ -355,6 +356,10 @@
 		client_id = APR_CLIENT_VOICE;
 		svc_idx = 6;
 		svc_id = APR_SVC_SRD;
+	} else if (!strncmp(svc_name, "USM", 3)) {
+		client_id = APR_CLIENT_AUDIO;
+		svc_idx = 8;
+		svc_id = APR_SVC_USM;
 	} else {
 		pr_err("APR: Wrong svc name\n");
 		goto done;
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_mvs.c b/arch/arm/mach-msm/qdsp6v2/audio_mvs.c
index 2dae9a8..0b4997c 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_mvs.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_mvs.c
@@ -38,7 +38,7 @@
 
 struct audio_mvs_buf_node {
 	struct list_head list;
-	struct msm_audio_mvs_frame frame;
+	struct q6_msm_audio_mvs_frame frame;
 };
 
 struct audio_mvs_info_type {
@@ -47,6 +47,7 @@
 	uint32_t mvs_mode;
 	uint32_t rate_type;
 	uint32_t dtx_mode;
+	struct q_min_max_rate min_max_rate;
 
 	struct list_head in_queue;
 	struct list_head free_in_queue;
@@ -110,7 +111,8 @@
 			 * Bits 0-3: Frame rate
 			 * Bits 4-7: Frame type
 			 */
-			buf_node->frame.frame_type = ((*voc_pkt) & 0xF0) >> 4;
+			buf_node->frame.header.frame_type =
+						((*voc_pkt) & 0xF0) >> 4;
 			voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
 			buf_node->frame.len = pkt_len - DSP_FRAME_HDR_LEN;
@@ -124,7 +126,7 @@
 		}
 
 		case MVS_MODE_IS127: {
-			buf_node->frame.frame_type = 0;
+			buf_node->frame.header.packet_rate = (*voc_pkt) & 0x0F;
 			voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
 			buf_node->frame.len = pkt_len - DSP_FRAME_HDR_LEN;
@@ -147,7 +149,7 @@
 			 * Header format:
 			 * Bits 0-1: Frame type
 			 */
-			buf_node->frame.frame_type = (*voc_pkt) & 0x03;
+			buf_node->frame.header.frame_type = (*voc_pkt) & 0x03;
 			voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
 			/* There are two frames in the buffer. Length of the
@@ -177,7 +179,8 @@
 				 * Header format:
 				 * Bits 0-1: Frame type
 				 */
-				buf_node->frame.frame_type = (*voc_pkt) & 0x03;
+				buf_node->frame.header.frame_type =
+							(*voc_pkt) & 0x03;
 				voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
 				/* There are two frames in the buffer. Length
@@ -213,7 +216,7 @@
 			 * Bits 0-1: Frame type
 			 * Bits 2-3: Frame rate
 			 */
-			buf_node->frame.frame_type = (*voc_pkt) & 0x03;
+			buf_node->frame.header.frame_type = (*voc_pkt) & 0x03;
 			voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
 			/* There are two frames in the buffer. Length of the
@@ -244,7 +247,8 @@
 				 * Bits 0-1: Frame type
 				 * Bits 2-3: Frame rate
 				 */
-				buf_node->frame.frame_type = (*voc_pkt) & 0x03;
+				buf_node->frame.header.frame_type =
+							(*voc_pkt) & 0x03;
 				voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
 				/* There are two frames in the buffer. Length
@@ -267,8 +271,25 @@
 			break;
 		}
 
+		case MVS_MODE_4GV_NB:
+		case MVS_MODE_4GV_WB: {
+			/* Remove the DSP frame info header.
+			 * Header format:
+			 * Bits 0-3: frame rate
+			 */
+			buf_node->frame.header.packet_rate = (*voc_pkt) & 0x0F;
+			voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
+			buf_node->frame.len = pkt_len - DSP_FRAME_HDR_LEN;
+
+			memcpy(&buf_node->frame.voc_pkt[0],
+				voc_pkt,
+				buf_node->frame.len);
+			list_add_tail(&buf_node->list, &audio->out_queue);
+			break;
+		}
+
 		default: {
-			buf_node->frame.frame_type = 0;
+			buf_node->frame.header.frame_type = 0;
 
 			buf_node->frame.len = pkt_len;
 
@@ -314,8 +335,9 @@
 			 * Bits 0-3: Frame rate
 			 * Bits 4-7: Frame type
 			 */
-			*voc_pkt = ((buf_node->frame.frame_type & 0x0F) << 4) |
-				   (rate_type & 0x0F);
+			*voc_pkt =
+			    ((buf_node->frame.header.frame_type & 0x0F) << 4) |
+			    (rate_type & 0x0F);
 			voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
 			*pkt_len = buf_node->frame.len + DSP_FRAME_HDR_LEN;
@@ -333,7 +355,7 @@
 			 * Bits 0-3: Frame rate
 			 * Bits 4-7: Frame type
 			 */
-			*voc_pkt = rate_type & 0x0F;
+			*voc_pkt = buf_node->frame.header.packet_rate & 0x0F;
 			voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
 			*pkt_len = buf_node->frame.len + DSP_FRAME_HDR_LEN;
@@ -353,7 +375,7 @@
 			/* Add the first DSP frame info header. Header format:
 			 * Bits 0-1: Frame type
 			 */
-			*voc_pkt = buf_node->frame.frame_type & 0x03;
+			*voc_pkt = buf_node->frame.header.frame_type & 0x03;
 			voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
 			*pkt_len = buf_node->frame.len + DSP_FRAME_HDR_LEN;
@@ -376,7 +398,8 @@
 				 * Header format:
 				 * Bits 0-1: Frame type
 				 */
-				*voc_pkt = buf_node->frame.frame_type & 0x03;
+				*voc_pkt = buf_node->frame.header.frame_type
+						& 0x03;
 				voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
 				*pkt_len = *pkt_len +
@@ -409,7 +432,7 @@
 			 * Bits 2-3: Frame rate
 			 */
 			*voc_pkt = ((rate_type & 0x0F) << 2) |
-				   (buf_node->frame.frame_type & 0x03);
+				   (buf_node->frame.header.frame_type & 0x03);
 			voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
 			*pkt_len = buf_node->frame.len + DSP_FRAME_HDR_LEN;
@@ -434,7 +457,7 @@
 				 * Bits 2-3: Frame rate
 				 */
 				*voc_pkt = ((rate_type & 0x0F) << 2) |
-					   (buf_node->frame.frame_type & 0x03);
+				     (buf_node->frame.header.frame_type & 0x03);
 				voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
 
 				*pkt_len = *pkt_len +
@@ -458,6 +481,23 @@
 			break;
 		}
 
+		case MVS_MODE_4GV_NB:
+		case MVS_MODE_4GV_WB: {
+			/* Add the DSP frame info header. Header format:
+			 * Bits 0-3 : Frame rate
+			*/
+			*voc_pkt = buf_node->frame.header.packet_rate & 0x0F;
+			voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
+			*pkt_len = buf_node->frame.len + DSP_FRAME_HDR_LEN;
+
+			memcpy(voc_pkt,
+				&buf_node->frame.voc_pkt[0],
+				buf_node->frame.len);
+
+			list_add_tail(&buf_node->list, &audio->free_in_queue);
+			break;
+		}
+
 		default: {
 			*pkt_len = buf_node->frame.len;
 
@@ -487,6 +527,14 @@
 		media_type = VSS_MEDIA_ID_EVRC_MODEM;
 		break;
 
+	case MVS_MODE_4GV_NB:
+		media_type = VSS_MEDIA_ID_4GV_NB_MODEM;
+		break;
+
+	case MVS_MODE_4GV_WB:
+		media_type = VSS_MEDIA_ID_4GV_WB_MODEM;
+		break;
+
 	case MVS_MODE_AMR:
 		media_type = VSS_MEDIA_ID_AMR_NB_MODEM;
 		break;
@@ -533,6 +581,7 @@
 
 	switch (mvs_mode) {
 	case MVS_MODE_IS127:
+	case MVS_MODE_4GV_NB:
 	case MVS_MODE_AMR:
 	case MVS_MODE_LINEAR_PCM:
 	case MVS_MODE_PCM:
@@ -541,6 +590,7 @@
 		network_type = VSS_NETWORK_ID_VOIP_NB;
 		break;
 
+	case MVS_MODE_4GV_WB:
 	case MVS_MODE_AMR_WB:
 	case MVS_MODE_PCM_WB:
 		network_type = VSS_NETWORK_ID_VOIP_WB;
@@ -576,7 +626,8 @@
 		    audio_mvs_get_media_type(audio->mvs_mode, audio->rate_type),
 		    audio_mvs_get_rate(audio->mvs_mode, audio->rate_type),
 		    audio_mvs_get_network_type(audio->mvs_mode),
-		    audio->dtx_mode);
+		    audio->dtx_mode,
+		    audio->min_max_rate);
 
 		audio->state = AUDIO_MVS_STARTED;
 	} else {
@@ -729,7 +780,7 @@
 		if ((audio->state == AUDIO_MVS_STARTED) &&
 		    (!list_empty(&audio->out_queue))) {
 
-			if (count >= sizeof(struct msm_audio_mvs_frame)) {
+			if (count >= sizeof(struct q6_msm_audio_mvs_frame)) {
 				buf_node = list_first_entry(&audio->out_queue,
 						struct audio_mvs_buf_node,
 						list);
@@ -737,11 +788,11 @@
 
 				rc = copy_to_user(buf,
 					&buf_node->frame,
-					sizeof(struct msm_audio_mvs_frame));
+					sizeof(struct q6_msm_audio_mvs_frame));
 
 				if (rc == 0) {
 					rc = buf_node->frame.len +
-					    sizeof(buf_node->frame.frame_type) +
+					    sizeof(buf_node->frame.header) +
 					    sizeof(buf_node->frame.len);
 				} else {
 					pr_err("%s: Copy to user retuned %d",
@@ -755,7 +806,7 @@
 			} else {
 				pr_err("%s: Read count %d < sizeof(frame) %d",
 				       __func__, count,
-				       sizeof(struct msm_audio_mvs_frame));
+				       sizeof(struct q6_msm_audio_mvs_frame));
 
 				rc = -ENOMEM;
 			}
@@ -799,7 +850,7 @@
 		mutex_lock(&audio->in_lock);
 
 		if (audio->state == AUDIO_MVS_STARTED) {
-			if (count <= sizeof(struct msm_audio_mvs_frame)) {
+			if (count <= sizeof(struct q6_msm_audio_mvs_frame)) {
 				if (!list_empty(&audio->free_in_queue)) {
 					buf_node =
 					list_first_entry(&audio->free_in_queue,
@@ -818,7 +869,7 @@
 			} else {
 				pr_err("%s: Write count %d < sizeof(frame) %d",
 				       __func__, count,
-				       sizeof(struct msm_audio_mvs_frame));
+				       sizeof(struct q6_msm_audio_mvs_frame));
 
 				rc = -ENOMEM;
 			}
@@ -863,7 +914,8 @@
 		config.mvs_mode = audio->mvs_mode;
 		config.rate_type = audio->rate_type;
 		config.dtx_mode = audio->dtx_mode;
-
+		config.min_max_rate.min_rate = audio->min_max_rate.min_rate;
+		config.min_max_rate.max_rate = audio->min_max_rate.max_rate;
 		mutex_unlock(&audio->lock);
 
 		rc = copy_to_user((void *)arg, &config, sizeof(config));
@@ -888,6 +940,10 @@
 				audio->mvs_mode = config.mvs_mode;
 				audio->rate_type = config.rate_type;
 				audio->dtx_mode = config.dtx_mode;
+				audio->min_max_rate.min_rate =
+						config.min_max_rate.min_rate;
+				audio->min_max_rate.max_rate =
+						config.min_max_rate.max_rate;
 			} else {
 				pr_err("%s: Set confg called in state %d\n",
 				       __func__, audio->state);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
index a1b1070..c1b5e8b 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils_aio.c
@@ -1009,8 +1009,8 @@
 			/* EOS buffer handled in driver */
 			list_add_tail(&buf_node->list, &audio->out_queue);
 			spin_unlock_irqrestore(&audio->dsp_lock, flags);
-		}
-		if (buf_node->meta_info.meta_in.nflags & AUDIO_DEC_EOS_SET) {
+		} else if (buf_node->meta_info.meta_in.nflags
+				   & AUDIO_DEC_EOS_SET) {
 			if (!audio->wflush) {
 				pr_debug("%s[%p]:Send EOS cmd at i/p\n",
 					__func__, audio);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_wmapro.c b/arch/arm/mach-msm/qdsp6v2/audio_wmapro.c
index 37cbfac..98d1b30 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_wmapro.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_wmapro.c
@@ -109,7 +109,8 @@
 			rc = -EINVAL;
 			break;
 		}
-		if (wmapro_config->validbitspersample == 16) {
+		if ((wmapro_config->validbitspersample == 16) ||
+			(wmapro_config->validbitspersample == 24)) {
 			wmapro_cfg.valid_bits_per_sample =
 				wmapro_config->validbitspersample;
 		} else {
diff --git a/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c b/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c
index cd1fe4c..16258eb 100644
--- a/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c
+++ b/arch/arm/mach-msm/qdsp6v2/lpa_if_hdmi.c
@@ -28,7 +28,7 @@
 #include <sound/dai.h>
 #include "q6core.h"
 
-#define DMA_ALLOC_BUF_SZ		(SZ_4K * 6)
+#define DMA_ALLOC_BUF_SZ		(SZ_4K * 16)
 
 #define HDMI_AUDIO_FIFO_WATER_MARK	4
 
@@ -74,8 +74,6 @@
 	pending = (intrsrc
 		   & (UNDER_CH(dma_ch) | PER_CH(dma_ch) | ERR_CH(dma_ch)));
 
-	pr_debug("pending = 0x%08x\n", pending);
-
 	if (pending & UNDER_CH(dma_ch))
 		pr_err("under run\n");
 	if (pending & ERR_CH(dma_ch))
@@ -104,10 +102,9 @@
 
 	dai_start_hdmi(lpa_if->dma_ch);
 
-	mb();
-
 	hdmi_audio_enable(1, HDMI_AUDIO_FIFO_WATER_MARK);
-	mb();
+
+	hdmi_audio_packet_enable(1);
 	return 0;
 }
 
@@ -121,7 +118,7 @@
 	dma_params.period_size = lpa_if->dma_period_sz;
 	dma_params.channels = 2;
 
-	lpa_if->dma_ch = 0;
+	lpa_if->dma_ch = 4;
 	dai_set_params(lpa_if->dma_ch, &dma_params);
 
 	register_dma_irq_handler(lpa_if->dma_ch, lpa_if_irq, (void *)lpa_if);
@@ -191,7 +188,7 @@
 			pr_debug("%s:failed to copy from user\n", __func__);
 			rc = -EFAULT;
 		}
-		if (lpa_if->dma_period_sz > DMA_ALLOC_BUF_SZ) {
+		if ((lpa_if->dma_period_sz * 2) > DMA_ALLOC_BUF_SZ) {
 			pr_err("Dma buffer size greater than allocated size\n");
 			return -EINVAL;
 		}
@@ -228,8 +225,11 @@
 
 	file->private_data = lpa_if_ptr;
 	dma_buf_index = 0;
+	lpa_if_ptr->cpu_buf = 0;
+	lpa_if_ptr->dma_buf = 0;
 
 	core_req_bus_bandwith(AUDIO_IF_BUS_ID, 100000, 0);
+	mb();
 
 	return 0;
 }
@@ -242,9 +242,6 @@
 	const char __user *start = buf;
 	int xfer, rc;
 
-	pr_debug("count %u cpu_buf %d dma_buf %d\n",
-		(unsigned int)count, lpa_if->cpu_buf, lpa_if->dma_buf);
-
 	mutex_lock(&lpa_if->lock);
 
 	if (dma_buf_index < 2) {
@@ -257,6 +254,7 @@
 			goto end;
 
 		}
+		mb();
 		pr_debug("prefill: count %u  audio_buf[%u].size %u\n",
 			 count, dma_buf_index, ab->size);
 
@@ -313,15 +311,20 @@
 static int lpa_if_release(struct inode *inode, struct file *file)
 {
 	struct lpa_if *lpa_if = file->private_data;
-	hdmi_audio_enable(0, HDMI_AUDIO_FIFO_WATER_MARK);
 
-	smp_mb();
+	hdmi_audio_packet_enable(0);
+
+	wait_for_dma_cnt_stop(lpa_if->dma_ch);
+
+	hdmi_audio_enable(0, HDMI_AUDIO_FIFO_WATER_MARK);
 
 	if (lpa_if->config) {
 		unregister_dma_irq_handler(lpa_if->dma_ch);
 		dai_stop_hdmi(lpa_if->dma_ch);
 		lpa_if->config = 0;
 	}
+	core_req_bus_bandwith(AUDIO_IF_BUS_ID, 0, 0);
+
 	return 0;
 }
 
diff --git a/arch/arm/mach-msm/qdsp6v2/pcm_out.c b/arch/arm/mach-msm/qdsp6v2/pcm_out.c
index 75975cc..a4a6b72 100644
--- a/arch/arm/mach-msm/qdsp6v2/pcm_out.c
+++ b/arch/arm/mach-msm/qdsp6v2/pcm_out.c
@@ -380,7 +380,7 @@
 	while (count > 0) {
 		rc = wait_event_timeout(pcm->write_wait,
 				(atomic_read(&pcm->out_count) ||
-				atomic_read(&pcm->out_stopped)), 5 * HZ);
+				atomic_read(&pcm->out_stopped)), 1 * HZ);
 		if (!rc) {
 			pr_err("%s: wait_event_timeout failed for session %d\n",
 				__func__, pcm->ac->session);
diff --git a/arch/arm/mach-msm/qdsp6v2/q6voice.c b/arch/arm/mach-msm/qdsp6v2/q6voice.c
index 7472849..1ab615a 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6voice.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6voice.c
@@ -1117,10 +1117,12 @@
 
 	/* Set encoder properties. */
 	switch (common.mvs_info.media_type) {
+	case VSS_MEDIA_ID_4GV_NB_MODEM:
+	case VSS_MEDIA_ID_4GV_WB_MODEM:
 	case VSS_MEDIA_ID_EVRC_MODEM: {
 		struct cvs_set_cdma_enc_minmax_rate_cmd cvs_set_cdma_rate;
 
-		pr_info("%s: Setting EVRC min-max rate\n", __func__);
+		pr_info("%s: Setting CDMA min-max rate\n", __func__);
 
 		cvs_set_cdma_rate.hdr.hdr_field =
 				APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
@@ -1133,14 +1135,16 @@
 		cvs_set_cdma_rate.hdr.token = 0;
 		cvs_set_cdma_rate.hdr.opcode =
 				VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE;
-		cvs_set_cdma_rate.cdma_rate.min_rate = common.mvs_info.rate;
-		cvs_set_cdma_rate.cdma_rate.max_rate = common.mvs_info.rate;
+		cvs_set_cdma_rate.cdma_rate.min_rate =
+				common.mvs_info.q_min_max_rate.min_rate;
+		cvs_set_cdma_rate.cdma_rate.max_rate =
+				common.mvs_info.q_min_max_rate.max_rate;
 
 		v->cvs_state = CMD_STATUS_FAIL;
 
 		ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_cdma_rate);
 		if (ret < 0) {
-			pr_err("%s: Error %d sending SET_EVRC_MINMAX_RATE\n",
+			pr_err("%s: Error %d sending CDMA_SET_ENC_MINMAX_RATE\n",
 			       __func__, ret);
 
 			goto done;
@@ -1156,6 +1160,10 @@
 			goto done;
 		}
 
+		if ((common.mvs_info.media_type == VSS_MEDIA_ID_4GV_NB_MODEM) ||
+		(common.mvs_info.media_type == VSS_MEDIA_ID_4GV_WB_MODEM))
+			ret = voice_set_dtx(v);
+
 		break;
 	}
 
@@ -2472,12 +2480,14 @@
 void voice_config_vocoder(uint32_t media_type,
 			  uint32_t rate,
 			  uint32_t network_type,
-			  uint32_t dtx_mode)
+			  uint32_t dtx_mode,
+			  struct q_min_max_rate q_min_max_rate)
 {
 	common.mvs_info.media_type = media_type;
 	common.mvs_info.rate = rate;
 	common.mvs_info.network_type = network_type;
 	common.mvs_info.dtx_mode = dtx_mode;
+	common.mvs_info.q_min_max_rate = q_min_max_rate;
 }
 
 static int32_t modem_mvm_callback(struct apr_client_data *data, void *priv)
diff --git a/arch/arm/mach-msm/qdsp6v2/snddev_hdmi.c b/arch/arm/mach-msm/qdsp6v2/snddev_hdmi.c
index 4eeb654..9b8346d 100644
--- a/arch/arm/mach-msm/qdsp6v2/snddev_hdmi.c
+++ b/arch/arm/mach-msm/qdsp6v2/snddev_hdmi.c
@@ -102,7 +102,7 @@
 	snddev_hdmi_active = 0;
 
 	if (snddev_hdmi_data->on_apps) {
-		pr_debug("%s open done\n", dev_info->name);
+		pr_debug("%s Closed\n", dev_info->name);
 
 		mutex_unlock(&snddev_hdmi_lock);
 		return 0;
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/Makefile b/arch/arm/mach-msm/qdsp6v2/ultrasound/Makefile
new file mode 100644
index 0000000..540119b
--- /dev/null
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/Makefile
@@ -0,0 +1,2 @@
+obj-y += q6usm.o usf.o
+EXTRA_CFLAGS += -I$(src)/..
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.c
new file mode 100644
index 0000000..d48df06
--- /dev/null
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.c
@@ -0,0 +1,1162 @@
+/* Copyright (c) 2011, 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
+ * 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/fs.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/dma-mapping.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/msm_audio.h>
+#include <sound/apr_audio.h>
+#include "q6usm.h"
+
+/* The driver version*/
+#define DRV_VERSION "1.0"
+
+#define SESSION_MAX 0x02 /* aDSP:USM limit */
+
+#define READDONE_IDX_STATUS     0
+#define READDONE_IDX_BUFFER     1
+#define READDONE_IDX_SIZE       2
+#define READDONE_IDX_OFFSET     3
+#define READDONE_IDX_MSW_TS     4
+#define READDONE_IDX_LSW_TS     5
+#define READDONE_IDX_FLAGS      6
+#define READDONE_IDX_NUMFRAMES  7
+#define READDONE_IDX_ID         8
+
+#define WRITEDONE_IDX_STATUS    0
+
+/* Standard timeout in the asynchronous ops */
+#define Q6USM_TIMEOUT_JIFFIES	(3*HZ) /* 3 sec */
+
+/* cyclic buffer with 1 gap support */
+#define USM_MIN_BUF_CNT 3
+
+static DEFINE_MUTEX(session_lock);
+
+static struct us_client *session[SESSION_MAX];
+static int32_t q6usm_mmapcallback(struct apr_client_data *data, void *priv);
+static int32_t q6usm_callback(struct apr_client_data *data, void *priv);
+static void q6usm_add_hdr(struct us_client *usc, struct apr_hdr *hdr,
+			  uint32_t pkt_size, bool cmd_flg);
+
+struct usm_mmap {
+	atomic_t ref_cnt;
+	atomic_t cmd_state;
+	wait_queue_head_t cmd_wait;
+	void *apr;
+};
+
+static struct usm_mmap this_mmap;
+
+static int q6usm_session_alloc(struct us_client *usc)
+{
+	int ind = 0;
+
+	mutex_lock(&session_lock);
+	for (ind = 0; ind < SESSION_MAX; ++ind) {
+		if (!session[ind]) {
+			session[ind] = usc;
+			mutex_unlock(&session_lock);
+			++ind; /* session id: 0 reserved */
+			pr_debug("%s: session[%d] was allocated\n",
+				  __func__, ind);
+			return ind;
+		}
+	}
+	mutex_unlock(&session_lock);
+	return -ENOMEM;
+}
+
+static void q6usm_session_free(struct us_client *usc)
+{
+	/* Session index was incremented during allocation */
+	uint16_t ind = (uint16_t)usc->session - 1;
+
+	pr_debug("%s: to free session[%d]\n", __func__, ind);
+	if (ind < SESSION_MAX) {
+		mutex_lock(&session_lock);
+		session[ind] = 0;
+		mutex_unlock(&session_lock);
+	}
+}
+
+int q6usm_us_client_buf_free(unsigned int dir,
+			     struct us_client *usc)
+{
+	struct us_port_data *port;
+	int rc = 0;
+	uint32_t size = 0;
+
+	if ((usc == NULL) ||
+	    ((dir != IN) && (dir != OUT)))
+		return -EINVAL;
+
+	mutex_lock(&usc->cmd_lock);
+	port = &usc->port[dir];
+	if (port == NULL) {
+		mutex_unlock(&usc->cmd_lock);
+		return -EINVAL;
+	}
+
+	if (port->data == NULL) {
+		mutex_unlock(&usc->cmd_lock);
+		return 0;
+	}
+
+	rc = q6usm_memory_unmap(usc, port->phys, dir);
+	if (rc)
+		pr_err("%s: CMD Memory_unmap* failed\n", __func__);
+
+	pr_debug("%s: data[%p]phys[%p][%p]\n", __func__,
+		 (void *)port->data, (void *)port->phys, (void *)&port->phys);
+	size = port->buf_size * port->buf_cnt;
+	dma_free_coherent(NULL, size, port->data, port->phys);
+	port->data = NULL;
+	port->phys = 0;
+	port->buf_size = 0;
+	port->buf_cnt = 0;
+
+	mutex_unlock(&usc->cmd_lock);
+	return 0;
+}
+
+void q6usm_us_client_free(struct us_client *usc)
+{
+	int loopcnt = 0;
+	struct us_port_data *port;
+
+	if ((usc == NULL) ||
+	    !(usc->session))
+		return;
+
+	for (loopcnt = 0; loopcnt <= OUT; ++loopcnt) {
+		port = &usc->port[loopcnt];
+		if (port->data == NULL)
+			continue;
+		pr_debug("%s: loopcnt = %d\n", __func__, loopcnt);
+		q6usm_us_client_buf_free(loopcnt, usc);
+	}
+	q6usm_session_free(usc);
+	apr_deregister(usc->apr);
+
+	pr_debug("%s: APR De-Register\n", __func__);
+
+	if (atomic_read(&this_mmap.ref_cnt) <= 0) {
+		pr_err("%s: APR Common Port Already Closed\n", __func__);
+		goto done;
+	}
+
+	atomic_dec(&this_mmap.ref_cnt);
+	if (atomic_read(&this_mmap.ref_cnt) == 0) {
+		apr_deregister(this_mmap.apr);
+		pr_debug("%s: APR De-Register common port\n", __func__);
+	}
+done:
+	kfree(usc);
+	pr_debug("%s:\n", __func__);
+	return;
+}
+
+struct us_client *q6usm_us_client_alloc(
+	void (*cb)(uint32_t, uint32_t, uint32_t *, void *),
+	void *priv)
+{
+	struct us_client *usc;
+	int n;
+	int lcnt = 0;
+
+	usc = kzalloc(sizeof(struct us_client), GFP_KERNEL);
+	if (usc == NULL)
+		return NULL;
+	n = q6usm_session_alloc(usc);
+	if (n <= 0)
+		goto fail_session;
+	usc->session = n;
+	usc->cb = cb;
+	usc->priv = priv;
+	usc->apr = apr_register("ADSP", "USM", \
+				(apr_fn)q6usm_callback,\
+				((usc->session) << 8 | 0x0001),\
+				usc);
+
+	if (usc->apr == NULL) {
+		pr_err("%s: Registration with APR failed\n", __func__);
+		goto fail;
+	}
+	pr_info("%s: Registering the common port with APR\n", __func__);
+	if (atomic_read(&this_mmap.ref_cnt) == 0) {
+		this_mmap.apr = apr_register("ADSP", "USM",
+					     (apr_fn)q6usm_mmapcallback,
+					     0x0FFFFFFFF, &this_mmap);
+		if (this_mmap.apr == NULL) {
+			pr_err("%s: USM port registration failed\n",
+			       __func__);
+			goto fail;
+		}
+	}
+
+	atomic_inc(&this_mmap.ref_cnt);
+	init_waitqueue_head(&usc->cmd_wait);
+	mutex_init(&usc->cmd_lock);
+	for (lcnt = 0; lcnt <= OUT; ++lcnt) {
+		mutex_init(&usc->port[lcnt].lock);
+		spin_lock_init(&usc->port[lcnt].dsp_lock);
+	}
+	atomic_set(&usc->cmd_state, 0);
+
+	return usc;
+fail:
+	q6usm_us_client_free(usc);
+	return NULL;
+fail_session:
+	kfree(usc);
+	return NULL;
+}
+
+int q6usm_us_client_buf_alloc(unsigned int dir,
+			      struct us_client *usc,
+			      unsigned int bufsz,
+			      unsigned int bufcnt)
+{
+	int rc = 0;
+	struct us_port_data *port = NULL;
+	unsigned int size = bufsz*bufcnt;
+
+	if ((usc == NULL) ||
+	    ((dir != IN) && (dir != OUT)) || (size == 0) ||
+	    (usc->session <= 0 || usc->session > SESSION_MAX) ||
+	    (bufcnt < USM_MIN_BUF_CNT)) {
+		pr_err("%s: wrong parameters: size=%d; bufcnt=%d\n",
+		       __func__, size, bufcnt);
+		return -EINVAL;
+	}
+
+	mutex_lock(&usc->cmd_lock);
+
+	port = &usc->port[dir];
+
+	port->data = dma_alloc_coherent(NULL, size, &(port->phys), GFP_KERNEL);
+	if (port->data == NULL) {
+		pr_err("%s: US region allocation failed\n", __func__);
+		mutex_unlock(&usc->cmd_lock);
+		return -ENOMEM;
+	}
+
+	port->buf_cnt = bufcnt;
+	port->buf_size = bufsz;
+	pr_debug("%s: data[%p]; phys[%p]; [%p]\n", __func__,
+		 (void *)port->data,
+		 (void *)port->phys,
+		 (void *)&port->phys);
+
+	rc = q6usm_memory_map(usc, port->phys, dir, size, 1);
+	if (rc < 0) {
+		pr_err("%s: CMD Memory_map failed\n", __func__);
+		mutex_unlock(&usc->cmd_lock);
+		q6usm_us_client_buf_free(dir, usc);
+	} else {
+		mutex_unlock(&usc->cmd_lock);
+		rc = 0;
+	}
+
+	return rc;
+}
+
+static int32_t q6usm_mmapcallback(struct apr_client_data *data, void *priv)
+{
+	uint32_t token;
+	uint32_t *payload = data->payload;
+
+	pr_debug("%s: ptr0[0x%x]; ptr1[0x%x]; opcode[0x%x];"
+		 "token[0x%x]; payload_s[%d]; src[%d]; dest[%d];\n",
+		 __func__, payload[0], payload[1], data->opcode, data->token,
+		 data->payload_size, data->src_port, data->dest_port);
+
+	if (data->opcode == APR_BASIC_RSP_RESULT) {
+		/* status field check */
+		if (payload[1]) {
+			pr_err("%s: wrong response[%d] on cmd [%d]\n",
+			       __func__, payload[1], payload[0]);
+		} else {
+			token = data->token;
+			switch (payload[0]) {
+			case USM_SESSION_CMD_MEMORY_MAP:
+			case USM_SESSION_CMD_MEMORY_UNMAP:
+				pr_debug("%s: cmd[0x%x]; result[0x%x]\n",
+					 __func__, payload[0], payload[1]);
+				if (atomic_read(&this_mmap.cmd_state)) {
+					atomic_set(&this_mmap.cmd_state, 0);
+					wake_up(&this_mmap.cmd_wait);
+				}
+				break;
+			default:
+				pr_debug("%s: wrong command[0x%x]\n",
+					 __func__, payload[0]);
+				break;
+			}
+		}
+	}
+	return 0;
+}
+
+
+static int32_t q6usm_callback(struct apr_client_data *data, void *priv)
+{
+	struct us_client *usc = (struct us_client *)priv;
+	unsigned long dsp_flags;
+	uint32_t *payload = data->payload;
+	uint32_t token = data->token;
+
+	if (usc == NULL) {
+		pr_err("%s: client info is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	if (data->opcode == APR_BASIC_RSP_RESULT) {
+		/* status field check */
+		if (payload[1]) {
+			pr_err("%s: wrong response[%d] on cmd [%d]\n",
+			       __func__, payload[1], payload[0]);
+			if (usc->cb)
+				usc->cb(data->opcode, token,
+					(uint32_t *)data->payload, usc->priv);
+		} else {
+			switch (payload[0]) {
+			case USM_SESSION_CMD_RUN:
+			case USM_STREAM_CMD_CLOSE:
+				if (token != usc->session) {
+					pr_err("%s: wrong token[%d]",
+					       __func__, token);
+					break;
+				}
+			case USM_STREAM_CMD_OPEN_READ:
+			case USM_STREAM_CMD_OPEN_WRITE:
+			case USM_STREAM_CMD_SET_ENC_PARAM:
+			case USM_DATA_CMD_MEDIA_FORMAT_UPDATE:
+				if (atomic_read(&usc->cmd_state)) {
+					atomic_set(&usc->cmd_state, 0);
+					wake_up(&usc->cmd_wait);
+				}
+				if (usc->cb)
+					usc->cb(data->opcode, token,
+						(uint32_t *)data->payload,
+						usc->priv);
+				break;
+			default:
+				pr_debug("%s: command[0x%x] wrong response\n",
+					 __func__, payload[0]);
+				break;
+			}
+		}
+		return 0;
+	}
+
+	switch (data->opcode) {
+	case USM_DATA_EVENT_READ_DONE: {
+		struct us_port_data *port = &usc->port[OUT];
+
+		pr_debug("%s: R-D: stat=%d; buff=%x; size=%d; off=%d\n",
+			 __func__,
+			 payload[READDONE_IDX_STATUS],
+			 payload[READDONE_IDX_BUFFER],
+			 payload[READDONE_IDX_SIZE],
+			 payload[READDONE_IDX_OFFSET]);
+		pr_debug("msw_ts=%d; lsw_ts=%d; flags=%d; id=%d; num=%d\n",
+			 payload[READDONE_IDX_MSW_TS],
+			 payload[READDONE_IDX_LSW_TS],
+			 payload[READDONE_IDX_FLAGS],
+			 payload[READDONE_IDX_ID],
+			 payload[READDONE_IDX_NUMFRAMES]);
+
+		spin_lock_irqsave(&port->dsp_lock, dsp_flags);
+		if (payload[READDONE_IDX_STATUS]) {
+			pr_err("%s: wrong READDONE[%d]; token[%d]\n",
+			       __func__,
+			       payload[READDONE_IDX_STATUS],
+			       token);
+			token = USM_WRONG_TOKEN;
+			spin_unlock_irqrestore(&port->dsp_lock,
+					       dsp_flags);
+			break;
+		}
+
+		if (port->expected_token != token) {
+			u32 cpu_buf = port->cpu_buf;
+			pr_err("%s: expected[%d] != token[%d]\n",
+				__func__, port->expected_token, token);
+			pr_info("%s: dsp_buf=%d; cpu_buf=%d;\n",
+				__func__,   port->dsp_buf, cpu_buf);
+
+			token = USM_WRONG_TOKEN;
+			/* To prevent data handle continiue */
+			port->expected_token = USM_WRONG_TOKEN;
+			spin_unlock_irqrestore(&port->dsp_lock,
+					       dsp_flags);
+			break;
+		} /* port->expected_token != data->token */
+
+		port->expected_token = token + 1;
+		if (port->expected_token == port->buf_cnt)
+			port->expected_token = 0;
+
+		/* gap support */
+		if (port->expected_token != port->cpu_buf) {
+			port->dsp_buf = port->expected_token;
+			token = port->dsp_buf; /* for callback */
+		} else
+			port->dsp_buf = token;
+
+		spin_unlock_irqrestore(&port->dsp_lock, dsp_flags);
+		break;
+	} /* case USM_DATA_EVENT_READ_DONE */
+
+	case USM_DATA_EVENT_WRITE_DONE: {
+		struct us_port_data *port = &usc->port[IN];
+
+		pr_debug("%s W-D: code[0x%x]; status[0x%x]; token[%d]",
+			 __func__,
+			 payload[0], payload[1], token);
+
+		if (payload[WRITEDONE_IDX_STATUS]) {
+			pr_err("%s: wrong WRITEDONE_IDX_STATUS[%d]\n",
+			       __func__,
+			       payload[WRITEDONE_IDX_STATUS]);
+			break;
+		}
+
+		spin_lock_irqsave(&port->dsp_lock, dsp_flags);
+		port->dsp_buf = token + 1;
+		if (port->dsp_buf == port->buf_cnt)
+			port->dsp_buf = 0;
+		spin_unlock_irqrestore(&port->dsp_lock, dsp_flags);
+
+		pr_info("%s: WRITE_DONE: token=%d; dsp_buf=%d; cpu_buf=%d\n",
+			__func__,
+			token, port->dsp_buf, port->cpu_buf);
+
+		break;
+	} /* case USM_DATA_EVENT_WRITE_DONE */
+
+	default:
+		pr_debug("%s: not supported code [0x%x]",
+			 __func__, data->opcode);
+		return 0;
+
+	} /* switch */
+
+	if (usc->cb)
+		usc->cb(data->opcode, token,
+			data->payload, usc->priv);
+
+	return 0;
+}
+
+uint32_t q6usm_get_ready_data(int dir, struct us_client *usc)
+{
+	uint32_t ret = 0xffffffff;
+
+	if ((usc != NULL) && ((dir == IN) || (dir == OUT)))
+		ret = usc->port[dir].dsp_buf;
+	return ret;
+}
+
+uint32_t q6usm_get_virtual_address(int dir,
+				   struct us_client *usc,
+				   struct vm_area_struct *vms)
+{
+	uint32_t ret = 0xffffffff;
+
+	if (vms && (usc != NULL) && ((dir == IN) || (dir == OUT))) {
+		struct us_port_data *port = &usc->port[dir];
+		ret = dma_mmap_coherent(NULL, vms,
+					port->data, port->phys,
+					port->buf_size * port->buf_cnt);
+	}
+	return ret;
+}
+
+static void q6usm_add_hdr(struct us_client *usc, struct apr_hdr *hdr,
+			  uint32_t pkt_size, bool cmd_flg)
+{
+	pr_debug("%s: pkt size=%d; cmd_flg=%d\n",
+		 __func__, pkt_size, cmd_flg);
+	pr_debug("**************\n");
+	mutex_lock(&usc->cmd_lock);
+	hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \
+				       APR_HDR_LEN(sizeof(struct apr_hdr)),\
+				       APR_PKT_VER);
+	hdr->src_svc = ((struct apr_svc *)usc->apr)->id;
+	hdr->src_domain = APR_DOMAIN_APPS;
+	hdr->dest_svc = APR_SVC_USM;
+	hdr->dest_domain = APR_DOMAIN_ADSP;
+	hdr->src_port = (usc->session << 8) | 0x0001;
+	hdr->dest_port = (usc->session << 8) | 0x0001;
+	if (cmd_flg) {
+		hdr->token = usc->session;
+		atomic_set(&usc->cmd_state, 1);
+	}
+	hdr->pkt_size  = APR_PKT_SIZE(APR_HDR_SIZE, pkt_size);
+	mutex_unlock(&usc->cmd_lock);
+	return;
+}
+
+static void q6usm_add_mmaphdr(struct us_client *usc, struct apr_hdr *hdr,
+			      uint32_t pkt_size, bool cmd_flg)
+{
+	pr_debug("%s: pkt size=%d cmd_flg=%d\n",
+		 __func__, pkt_size, cmd_flg);
+	pr_debug("**************\n");
+	hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \
+				       APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+	hdr->src_port = 0;
+	hdr->dest_port = 0;
+	if (cmd_flg) {
+		hdr->token = 0;
+		atomic_set(&this_mmap.cmd_state, 1);
+	}
+	hdr->pkt_size  = pkt_size;
+	return;
+}
+
+static uint32_t q6usm_ext2int_format(uint32_t ext_format)
+{
+	uint32_t int_format = INVALID_FORMAT;
+	switch (ext_format) {
+	case FORMAT_USPS_EPOS:
+		int_format = US_POINT_EPOS_FORMAT;
+		break;
+	case FORMAT_USRAW:
+		int_format = US_RAW_FORMAT;
+		break;
+	default:
+		pr_err("%s: Invalid format[%d]\n", __func__, ext_format);
+		break;
+	}
+
+	return int_format;
+}
+
+int q6usm_open_read(struct us_client *usc,
+		    uint32_t format)
+{
+	uint32_t int_format = INVALID_FORMAT;
+	int rc = 0x00;
+	struct usm_stream_cmd_open_read open;
+
+	pr_debug("%s: session[%d]", __func__, usc->session);
+
+	if ((usc == NULL) || (usc->apr == NULL)) {
+		pr_err("%s: client or its apr is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	q6usm_add_hdr(usc, &open.hdr, sizeof(open), true);
+	open.hdr.opcode = USM_STREAM_CMD_OPEN_READ;
+	open.src_endpoint = 0; /* AFE */
+	open.pre_proc_top = 0; /* No preprocessing required */
+
+	int_format = q6usm_ext2int_format(format);
+	if (int_format == INVALID_FORMAT)
+		return -EINVAL;
+
+	open.uMode = STREAM_PRIORITY_NORMAL;
+	open.format = int_format;
+
+	rc = apr_send_pkt(usc->apr, (uint32_t *) &open);
+	if (rc < 0) {
+		pr_err("%s: open failed op[0x%x]rc[%d]\n",
+		       __func__, open.hdr.opcode, rc);
+		goto fail_cmd;
+	}
+	rc = wait_event_timeout(usc->cmd_wait,
+				(atomic_read(&usc->cmd_state) == 0),
+				Q6USM_TIMEOUT_JIFFIES);
+	if (!rc) {
+		rc = -ETIME;
+		pr_err("%s: timeout, waited for OPEN_READ rc[%d]\n",
+		       __func__, rc);
+		goto fail_cmd;
+	} else
+		rc = 0;
+fail_cmd:
+	return rc;
+}
+
+
+int q6usm_enc_cfg_blk(struct us_client *usc, struct us_encdec_cfg* us_cfg)
+{
+	uint32_t int_format = INVALID_FORMAT;
+	struct usm_stream_cmd_encdec_cfg_blk  enc_cfg_obj;
+	struct usm_stream_cmd_encdec_cfg_blk  *enc_cfg = &enc_cfg_obj;
+	int rc = 0;
+	uint32_t total_cfg_size =
+		sizeof(struct usm_stream_cmd_encdec_cfg_blk);
+	uint32_t round_params_size = 0;
+	uint8_t  is_allocated = 0;
+
+
+	if ((usc == NULL) || (us_cfg == NULL)) {
+		pr_err("%s: wrong input", __func__);
+		return -EINVAL;
+	}
+
+	int_format = q6usm_ext2int_format(us_cfg->format_id);
+	if (int_format == INVALID_FORMAT) {
+		pr_err("%s: wrong input format[%d]",
+		       __func__, us_cfg->format_id);
+		return -EINVAL;
+	}
+
+	/* Transparent configuration data is after enc_cfg */
+	/* Integer number of u32s is requred */
+	round_params_size = ((us_cfg->params_size + 3)/4) * 4;
+	if (round_params_size > USM_MAX_CFG_DATA_SIZE) {
+		/* Dynamic allocated encdec_cfg_blk is required */
+		/* static part use */
+		round_params_size -= USM_MAX_CFG_DATA_SIZE;
+		total_cfg_size += round_params_size;
+		enc_cfg = kzalloc(total_cfg_size, GFP_KERNEL);
+		if (enc_cfg == NULL) {
+			pr_err("%s: enc_cfg[%d] allocation failed\n",
+			       __func__, total_cfg_size);
+			return -ENOMEM;
+		}
+		is_allocated = 1;
+	} else
+		round_params_size = 0;
+
+	q6usm_add_hdr(usc, &enc_cfg->hdr, total_cfg_size - APR_HDR_SIZE, true);
+
+	enc_cfg->hdr.opcode = USM_STREAM_CMD_SET_ENC_PARAM;
+	enc_cfg->param_id = USM_PARAM_ID_ENCDEC_ENC_CFG_BLK;
+	enc_cfg->param_size = sizeof(struct usm_encode_cfg_blk)+
+				round_params_size;
+	enc_cfg->enc_blk.frames_per_buf = 1;
+	enc_cfg->enc_blk.format_id = int_format;
+	enc_cfg->enc_blk.cfg_size = sizeof(struct usm_cfg_common)+
+				    USM_MAX_CFG_DATA_SIZE +
+				    round_params_size;
+	memcpy(&(enc_cfg->enc_blk.cfg_common), &(us_cfg->cfg_common),
+	       sizeof(struct usm_cfg_common));
+
+	/* Transparent data copy */
+	memcpy(enc_cfg->enc_blk.transp_data, us_cfg->params,
+	       us_cfg->params_size);
+	pr_info("%s: cfg_size[%d], params_size[%d]\n",
+		__func__,
+		enc_cfg->enc_blk.cfg_size,
+		us_cfg->params_size);
+	pr_info("%s: params[%d,%d,%d,%d, %d,%d,%d,%d]\n",
+		__func__,
+		enc_cfg->enc_blk.transp_data[0],
+		enc_cfg->enc_blk.transp_data[1],
+		enc_cfg->enc_blk.transp_data[2],
+		enc_cfg->enc_blk.transp_data[3],
+		enc_cfg->enc_blk.transp_data[4],
+		enc_cfg->enc_blk.transp_data[5],
+		enc_cfg->enc_blk.transp_data[6],
+		enc_cfg->enc_blk.transp_data[7]
+	       );
+	pr_info("%s: srate:%d, ch=%d, bps= %d; dmap:0x%x; dev_id=0x%x\n",
+		__func__, enc_cfg->enc_blk.cfg_common.sample_rate,
+		enc_cfg->enc_blk.cfg_common.ch_cfg,
+		enc_cfg->enc_blk.cfg_common.bits_per_sample,
+		enc_cfg->enc_blk.cfg_common.data_map,
+		enc_cfg->enc_blk.cfg_common.dev_id);
+
+	rc = apr_send_pkt(usc->apr, (uint32_t *) enc_cfg);
+	if (rc < 0) {
+		pr_err("%s:Comamnd open failed\n", __func__);
+		rc = -EINVAL;
+		goto fail_cmd;
+	}
+	rc = wait_event_timeout(usc->cmd_wait,
+				(atomic_read(&usc->cmd_state) == 0),
+				Q6USM_TIMEOUT_JIFFIES);
+	if (!rc) {
+		rc = -ETIME;
+		pr_err("%s: timeout opcode[0x%x]\n",
+		       __func__, enc_cfg->hdr.opcode);
+	} else
+		rc = 0;
+
+fail_cmd:
+	if (is_allocated == 1)
+		kfree(enc_cfg);
+
+	return rc;
+}
+
+int q6usm_dec_cfg_blk(struct us_client *usc, struct us_encdec_cfg *us_cfg)
+{
+
+	uint32_t int_format = INVALID_FORMAT;
+	struct usm_stream_media_format_update dec_cfg_obj;
+	struct usm_stream_media_format_update *dec_cfg = &dec_cfg_obj;
+
+	int rc = 0;
+	uint32_t total_cfg_size = sizeof(struct usm_stream_media_format_update);
+	uint32_t round_params_size = 0;
+	uint8_t  is_allocated = 0;
+
+
+	if ((usc == NULL) || (us_cfg == NULL)) {
+		pr_err("%s: wrong input", __func__);
+		return -EINVAL;
+	}
+
+	int_format = q6usm_ext2int_format(us_cfg->format_id);
+	if (int_format == INVALID_FORMAT) {
+		pr_err("%s: wrong input format[%d]",
+		       __func__, us_cfg->format_id);
+		return -EINVAL;
+	}
+
+	/* Transparent configuration data is after enc_cfg */
+	/* Integer number of u32s is requred */
+	round_params_size = ((us_cfg->params_size + 3)/4) * 4;
+	if (round_params_size > USM_MAX_CFG_DATA_SIZE) {
+		/* Dynamic allocated encdec_cfg_blk is required */
+		/* static part use */
+		round_params_size -= USM_MAX_CFG_DATA_SIZE;
+		total_cfg_size += round_params_size;
+		dec_cfg = kzalloc(total_cfg_size, GFP_KERNEL);
+		if (dec_cfg == NULL) {
+			pr_err("%s:dec_cfg[%d] allocation failed\n",
+			       __func__, total_cfg_size);
+			return -ENOMEM;
+		}
+		is_allocated = 1;
+	} else { /* static transp_data is enough */
+		round_params_size = 0;
+	}
+
+	q6usm_add_hdr(usc, &dec_cfg->hdr, total_cfg_size - APR_HDR_SIZE, true);
+
+	dec_cfg->hdr.opcode = USM_DATA_CMD_MEDIA_FORMAT_UPDATE;
+	dec_cfg->format_id = int_format;
+	dec_cfg->cfg_size = sizeof(struct usm_cfg_common) +
+			    USM_MAX_CFG_DATA_SIZE +
+			    round_params_size;
+	memcpy(&(dec_cfg->cfg_common), &(us_cfg->cfg_common),
+	       sizeof(struct usm_cfg_common));
+	/* Transparent data copy */
+	memcpy(dec_cfg->transp_data, us_cfg->params, us_cfg->params_size);
+	pr_info("%s: cfg_size[%d], params_size[%d]; parambytes[%d,%d,%d,%d]\n",
+		__func__,
+		dec_cfg->cfg_size,
+		us_cfg->params_size,
+		dec_cfg->transp_data[0],
+		dec_cfg->transp_data[1],
+		dec_cfg->transp_data[2],
+		dec_cfg->transp_data[3]
+	       );
+
+	rc = apr_send_pkt(usc->apr, (uint32_t *) dec_cfg);
+	if (rc < 0) {
+		pr_err("%s:Comamnd open failed\n", __func__);
+		rc = -EINVAL;
+		goto fail_cmd;
+	}
+	rc = wait_event_timeout(usc->cmd_wait,
+				(atomic_read(&usc->cmd_state) == 0),
+				Q6USM_TIMEOUT_JIFFIES);
+	if (!rc) {
+		rc = -ETIME;
+		pr_err("%s: timeout opcode[0x%x]\n",
+		       __func__, dec_cfg->hdr.opcode);
+	} else
+		rc = 0;
+
+fail_cmd:
+	if (is_allocated == 1)
+		kfree(dec_cfg);
+
+	return rc;
+}
+
+int q6usm_open_write(struct us_client *usc,
+		     uint32_t format)
+{
+	int rc = 0;
+	uint32_t int_format = INVALID_FORMAT;
+	struct usm_stream_cmd_open_write open;
+
+	pr_debug("%s: session[%d]", __func__, usc->session);
+
+	if ((usc == NULL) || (usc->apr == NULL)) {
+		pr_err("%s: APR handle NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	q6usm_add_hdr(usc, &open.hdr, sizeof(open), true);
+	open.hdr.opcode = USM_STREAM_CMD_OPEN_WRITE;
+
+	int_format = q6usm_ext2int_format(format);
+	if (int_format == INVALID_FORMAT) {
+		pr_err("%s: wrong format[%d]", __func__, format);
+		return -EINVAL;
+	}
+
+	open.format = int_format;
+
+	rc = apr_send_pkt(usc->apr, (uint32_t *) &open);
+	if (rc < 0) {
+		pr_err("%s:open failed op[0x%x]rc[%d]\n", \
+		       __func__, open.hdr.opcode, rc);
+		goto fail_cmd;
+	}
+	rc = wait_event_timeout(usc->cmd_wait,
+				(atomic_read(&usc->cmd_state) == 0),
+				Q6USM_TIMEOUT_JIFFIES);
+	if (!rc) {
+		rc = -ETIME;
+		pr_err("%s:timeout. waited for OPEN_WRITR rc[%d]\n",
+		       __func__, rc);
+		goto fail_cmd;
+	} else
+		rc = 0;
+
+fail_cmd:
+	return rc;
+}
+
+int q6usm_run(struct us_client *usc, uint32_t flags,
+	      uint32_t msw_ts, uint32_t lsw_ts)
+{
+	struct usm_stream_cmd_run run;
+	int rc = 0;
+
+	if ((usc == NULL) || (usc->apr == NULL)) {
+		pr_err("%s: APR handle NULL\n", __func__);
+		return -EINVAL;
+	}
+	q6usm_add_hdr(usc, &run.hdr, sizeof(run), true);
+
+	run.hdr.opcode = USM_SESSION_CMD_RUN;
+	run.flags    = flags;
+	run.msw_ts   = msw_ts;
+	run.lsw_ts   = lsw_ts;
+
+	rc = apr_send_pkt(usc->apr, (uint32_t *) &run);
+	if (rc < 0) {
+		pr_err("%s: Commmand run failed[%d]\n", __func__, rc);
+		goto fail_cmd;
+	}
+
+	rc = wait_event_timeout(usc->cmd_wait,
+				(atomic_read(&usc->cmd_state) == 0),
+				Q6USM_TIMEOUT_JIFFIES);
+	if (!rc) {
+		rc = -ETIME;
+		pr_err("%s: timeout. waited for run success rc[%d]\n",
+		       __func__, rc);
+	} else
+		rc = 0;
+
+fail_cmd:
+	return rc;
+}
+
+
+int q6usm_memory_map(struct us_client *usc, uint32_t buf_add, int dir,
+		     uint32_t bufsz, uint32_t bufcnt)
+{
+	struct usm_stream_cmd_memory_map mem_map;
+	int rc = 0;
+
+	if ((usc == NULL) || (usc->apr == NULL) || (this_mmap.apr == NULL)) {
+		pr_err("%s: APR handle NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	q6usm_add_mmaphdr(usc, &mem_map.hdr,
+			  sizeof(struct usm_stream_cmd_memory_map), true);
+	mem_map.hdr.opcode = USM_SESSION_CMD_MEMORY_MAP;
+
+	mem_map.buf_add = buf_add;
+	mem_map.buf_size = bufsz * bufcnt;
+	mem_map.mempool_id = 0;
+
+	pr_debug("%s: buf add[%x]  buf_add_parameter[%x]\n",
+		 __func__, mem_map.buf_add, buf_add);
+
+	rc = apr_send_pkt(this_mmap.apr, (uint32_t *) &mem_map);
+	if (rc < 0) {
+		pr_err("%s: mem_map op[0x%x]rc[%d]\n",
+		       __func__, mem_map.hdr.opcode, rc);
+		goto fail_cmd;
+	}
+
+	rc = wait_event_timeout(this_mmap.cmd_wait,
+				(atomic_read(&this_mmap.cmd_state) == 0),
+				Q6USM_TIMEOUT_JIFFIES);
+	if (!rc) {
+		rc = -ETIME;
+		pr_err("%s: timeout. waited for memory_map\n", __func__);
+	} else
+		rc = 0;
+fail_cmd:
+	return rc;
+}
+
+int q6usm_memory_unmap(struct us_client *usc, uint32_t buf_add, int dir)
+{
+	struct usm_stream_cmd_memory_unmap mem_unmap;
+	int rc = 0;
+
+	if ((usc == NULL) || (usc->apr == NULL) || (this_mmap.apr == NULL)) {
+		pr_err("%s: APR handle NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	q6usm_add_mmaphdr(usc, &mem_unmap.hdr,
+			  sizeof(struct usm_stream_cmd_memory_unmap), true);
+	mem_unmap.hdr.opcode = USM_SESSION_CMD_MEMORY_UNMAP;
+	mem_unmap.buf_add = buf_add;
+
+	rc = apr_send_pkt(this_mmap.apr, (uint32_t *) &mem_unmap);
+	if (rc < 0) {
+		pr_err("%s:mem_unmap op[0x%x]rc[%d]\n",
+		       __func__, mem_unmap.hdr.opcode, rc);
+		goto fail_cmd;
+	}
+
+	rc = wait_event_timeout(this_mmap.cmd_wait,
+				(atomic_read(&this_mmap.cmd_state) == 0),
+				Q6USM_TIMEOUT_JIFFIES);
+	if (!rc) {
+		rc = -ETIME;
+		pr_err("%s: timeout. waited for memory_map\n", __func__);
+	} else
+		rc = 0;
+fail_cmd:
+	return rc;
+}
+
+int q6usm_read(struct us_client *usc, uint32_t read_ind)
+{
+	struct usm_stream_cmd_read read;
+	struct us_port_data *port = NULL;
+	int rc = 0;
+	u32 read_counter = 0;
+	u32 loop_ind = 0;
+
+	if ((usc == NULL) || (usc->apr == NULL)) {
+		pr_err("%s: APR handle NULL\n", __func__);
+		return -EINVAL;
+	}
+	port = &usc->port[OUT];
+
+	if (read_ind > port->buf_cnt) {
+		pr_err("%s: wrong read_ind[%d]\n",
+		       __func__, read_ind);
+		return -EINVAL;
+	}
+	if (read_ind == port->cpu_buf) {
+		pr_err("%s: no free region\n", __func__);
+		return 0;
+	}
+
+	if (read_ind > port->cpu_buf) { /* 1 range */
+		read_counter = read_ind - port->cpu_buf;
+	} else { /* 2 ranges */
+		read_counter = (port->buf_cnt - port->cpu_buf) + read_ind;
+	}
+
+	q6usm_add_hdr(usc, &read.hdr, (sizeof(read) - APR_HDR_SIZE), false);
+
+	read.hdr.opcode = USM_DATA_CMD_READ;
+	read.buf_size = port->buf_size;
+
+	for (loop_ind = 0; loop_ind < read_counter; ++loop_ind) {
+		u32 temp_cpu_buf = port->cpu_buf;
+
+		read.buf_add = (uint32_t)(port->phys) +
+			       port->buf_size * (port->cpu_buf);
+		read.uid = port->cpu_buf;
+		read.hdr.token = port->cpu_buf;
+		read.counter = 1;
+
+		++(port->cpu_buf);
+		if (port->cpu_buf == port->buf_cnt)
+			port->cpu_buf = 0;
+
+		rc = apr_send_pkt(usc->apr, (uint32_t *) &read);
+
+		if (rc < 0) {
+			port->cpu_buf = temp_cpu_buf;
+
+			pr_err("%s:read op[0x%x]rc[%d]\n",
+			       __func__, read.hdr.opcode, rc);
+			break;
+		} else
+			rc = 0;
+	} /* bufs loop */
+
+	return rc;
+}
+
+int q6usm_write(struct us_client *usc, uint32_t write_ind)
+{
+	int rc = 0;
+	struct usm_stream_cmd_write cmd_write;
+	struct us_port_data *port = NULL;
+	u32 current_dsp_buf = 0;
+
+	if ((usc == NULL) || (usc->apr == NULL)) {
+		pr_err("%s: APR handle NULL\n", __func__);
+		return -EINVAL;
+	}
+	port = &usc->port[IN];
+
+	current_dsp_buf = port->dsp_buf;
+	/* free region, caused by new dsp_buf report from DSP, */
+	/* can be only extended */
+	if (port->cpu_buf >= current_dsp_buf) {
+		/* 2 -part free region, including empty buffer */
+		if ((write_ind <= port->cpu_buf)  &&
+		    (write_ind > current_dsp_buf)) {
+			pr_err("%s: wrong w_ind[%d]; d_buf=%d; c_buf=%d\n",
+			       __func__, write_ind,
+			       current_dsp_buf, port->cpu_buf);
+			return -EINVAL;
+		}
+	} else {
+		/* 1 -part free region */
+		if ((write_ind <= port->cpu_buf)  ||
+		    (write_ind > current_dsp_buf)) {
+			pr_err("%s: wrong w_ind[%d]; d_buf=%d; c_buf=%d\n",
+			       __func__, write_ind,
+			       current_dsp_buf, port->cpu_buf);
+			return -EINVAL;
+		}
+	}
+
+	q6usm_add_hdr(usc, &cmd_write.hdr,
+		      (sizeof(cmd_write) - APR_HDR_SIZE), false);
+
+	cmd_write.hdr.opcode = USM_DATA_CMD_WRITE;
+	cmd_write.buf_size = port->buf_size;
+
+	while (port->cpu_buf != write_ind) {
+		u32 temp_cpu_buf = port->cpu_buf;
+
+		cmd_write.buf_add = (uint32_t)(port->phys) +
+				    port->buf_size * (port->cpu_buf);
+		cmd_write.uid = port->cpu_buf;
+		cmd_write.hdr.token = port->cpu_buf;
+
+		pr_debug("%s:buf addr[0x%x] size[%d] token[%d] uid[%d]\n",
+			 __func__, cmd_write.buf_add, cmd_write.buf_size,
+			 cmd_write.hdr.token, cmd_write.uid);
+		pr_debug("%s: data=0x%p\n", __func__, port->data);
+
+		++(port->cpu_buf);
+		if (port->cpu_buf == port->buf_cnt)
+			port->cpu_buf = 0;
+
+		rc = apr_send_pkt(usc->apr, (uint32_t *) &cmd_write);
+
+		if (rc < 0) {
+			port->cpu_buf = temp_cpu_buf;
+			pr_err("%s:write op[0x%x];rc[%d];cpu_buf[%d]\n",
+			       __func__, cmd_write.hdr.opcode,
+			       rc, port->cpu_buf);
+			break;
+		}
+
+		rc = 0;
+	}
+
+	pr_debug("%s:exit: rc=%d; write_ind=%d; cpu_buf=%d; dsp_buf=%d\n",
+		__func__, rc, write_ind, port->cpu_buf, port->dsp_buf);
+
+	return rc;
+}
+
+bool q6usm_is_write_buf_full(struct us_client *usc, uint32_t* free_region)
+{
+	struct us_port_data *port = NULL;
+	u32 cpu_buf = 0;
+
+	if ((usc == NULL) || !free_region) {
+		pr_err("%s: input data wrong\n", __func__);
+		return false;
+	}
+	port = &usc->port[IN];
+	cpu_buf = port->cpu_buf + 1;
+	if (cpu_buf == port->buf_cnt)
+		cpu_buf = 0;
+
+	*free_region = port->dsp_buf;
+
+	return cpu_buf == *free_region;
+}
+
+int q6usm_cmd(struct us_client *usc, int cmd)
+{
+	struct apr_hdr hdr;
+	int rc = 0;
+	atomic_t *state;
+
+	if ((usc == NULL) || (usc->apr == NULL)) {
+		pr_err("%s: APR handle NULL\n", __func__);
+		return -EINVAL;
+	}
+	q6usm_add_hdr(usc, &hdr, (sizeof(hdr) - APR_HDR_SIZE), true);
+	switch (cmd) {
+	case CMD_CLOSE:
+		hdr.opcode = USM_STREAM_CMD_CLOSE;
+		state = &usc->cmd_state;
+		break;
+
+	default:
+		pr_err("%s:Invalid format[%d]\n", __func__, cmd);
+		goto fail_cmd;
+	}
+
+	pr_debug("%s:session[%d]opcode[0x%x] ", __func__,
+		 usc->session,  hdr.opcode);
+	rc = apr_send_pkt(usc->apr, (uint32_t *) &hdr);
+	if (rc < 0) {
+		pr_err("%s: Command 0x%x failed\n", __func__, hdr.opcode);
+		goto fail_cmd;
+	}
+	rc = wait_event_timeout(usc->cmd_wait, (atomic_read(state) == 0),
+				Q6USM_TIMEOUT_JIFFIES);
+	if (!rc) {
+		rc = -ETIME;
+		pr_err("%s:timeout. waited for response opcode[0x%x]\n",
+		       __func__, hdr.opcode);
+	} else
+		rc = 0;
+fail_cmd:
+	return rc;
+}
+
+static int __init q6usm_init(void)
+{
+	pr_debug("%s\n", __func__);
+	init_waitqueue_head(&this_mmap.cmd_wait);
+	memset(session, 0, sizeof(session));
+	return 0;
+}
+
+device_initcall(q6usm_init);
+
+MODULE_DESCRIPTION("Interface with QDSP6:USM");
+MODULE_VERSION(DRV_VERSION);
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.h b/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.h
new file mode 100644
index 0000000..fe12ee1
--- /dev/null
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.h
@@ -0,0 +1,109 @@
+/* Copyright (c) 2011, 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
+ * 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 __Q6_USM_H__
+#define __Q6_USM_H__
+
+#include <mach/qdsp6v2/apr_us.h>
+
+#define FORMAT_USPS_EPOS	0x00000000
+#define FORMAT_USRAW		0x00000001
+#define INVALID_FORMAT		0xffffffff
+
+#define IN			0x000
+#define OUT			0x001
+
+#define USM_WRONG_TOKEN		0xffffffff
+#define USM_UNDEF_TOKEN		0xfffffffe
+
+#define CMD_CLOSE		0x0004
+
+/* bit 0:1 represents priority of stream */
+#define STREAM_PRIORITY_NORMAL	0x0000
+#define STREAM_PRIORITY_LOW	0x0001
+#define STREAM_PRIORITY_HIGH	0x0002
+
+/* bit 4 represents META enable of encoded data buffer */
+#define BUFFER_META_ENABLE	0x0010
+
+struct us_region {
+	dma_addr_t	phys;
+	/* If == NULL, the region isn't allocated */
+	void		*data;
+	/* number of buffers in the region */
+	uint32_t	buf_cnt;
+	/* size of buffer */
+	uint32_t	buf_size;
+};
+
+struct us_port_data {
+	dma_addr_t	phys;
+	/* cyclic region of buffers with 1 gap */
+	void		*data;
+	/* number of buffers in the region */
+	uint32_t	buf_cnt;
+	/* size of buffer */
+	uint32_t	buf_size;
+	/* TX: write index */
+	uint32_t	dsp_buf;
+	/* TX: read index */
+	uint32_t	cpu_buf;
+	/* expected token from dsp */
+	uint32_t	expected_token;
+	/* read or write locks */
+	struct mutex	lock;
+	spinlock_t	dsp_lock;
+};
+
+struct us_client {
+	int			session;
+	/* idx:1 out port, 0: in port*/
+	struct us_port_data	port[2];
+
+	struct apr_svc		*apr;
+	struct mutex		cmd_lock;
+
+	atomic_t		cmd_state;
+	atomic_t		eos_state;
+	wait_queue_head_t	cmd_wait;
+
+	void (*cb)(uint32_t, uint32_t, uint32_t *, void *);
+	void			*priv;
+};
+
+int q6usm_run(struct us_client *usc, uint32_t flags,
+	      uint32_t msw_ts, uint32_t lsw_ts);
+int q6usm_cmd(struct us_client *usc, int cmd);
+int q6usm_us_client_buf_alloc(unsigned int dir, struct us_client *usc,
+			      unsigned int bufsz, unsigned int bufcnt);
+int q6usm_enc_cfg_blk(struct us_client *usc, struct us_encdec_cfg *us_cfg);
+int q6usm_dec_cfg_blk(struct us_client *usc, struct us_encdec_cfg *us_cfg);
+int q6usm_read(struct us_client *usc, uint32_t read_ind);
+struct us_client *q6usm_us_client_alloc(
+	void (*cb)(uint32_t, uint32_t, uint32_t *, void *),
+	void *priv);
+int q6usm_open_read(struct us_client *usc, uint32_t format);
+void q6usm_us_client_free(struct us_client *usc);
+int q6usm_memory_map(struct us_client *usc, uint32_t buf_add,
+		     int dir, uint32_t bufsz, uint32_t bufcnt);
+int q6usm_memory_unmap(struct us_client *usc, uint32_t buf_add,
+		       int dir);
+
+uint32_t q6usm_get_ready_data(int dir, struct us_client *usc);
+uint32_t q6usm_get_virtual_address(int dir, struct us_client *usc,
+				   struct vm_area_struct *vms);
+
+int q6usm_open_write(struct us_client *usc,  uint32_t format);
+int q6usm_write(struct us_client *usc, uint32_t write_ind);
+bool q6usm_is_write_buf_full(struct us_client *usc, uint32_t* free_region);
+
+#endif /* __Q6_USM_H__ */
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
new file mode 100644
index 0000000..bfe0006
--- /dev/null
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
@@ -0,0 +1,1006 @@
+/* Copyright (c) 2011, 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
+ * 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/fs.h>
+#include <linux/module.h>
+#include <linux/miscdevice.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/wait.h>
+#include <linux/input.h>
+#include <linux/uaccess.h>
+#include <linux/time.h>
+#include <asm/mach-types.h>
+#include <sound/apr_audio.h>
+#include <mach/qdsp6v2/usf.h>
+#include "q6usm.h"
+
+/* The driver version*/
+#define DRV_VERSION "1.0"
+
+/* Standard timeout in the asynchronous ops */
+#define USF_TIMEOUT_JIFFIES (3*HZ) /* 3 sec */
+
+/* Undefined USF device */
+#define USF_UNDEF_DEV_ID 0xffff
+
+/* RX memory mapping flag */
+#define	USF_VM_WRITE	2
+
+/* The driver states */
+enum usf_state_type {
+	USF_IDLE_STATE,
+	USF_OPENED_STATE,
+	USF_CONFIGURED_STATE,
+	USF_WORK_STATE,
+	USF_ERROR_STATE
+};
+
+struct usf_xx_type {
+	/* Name of the client - event calculator */
+	char client_name[USF_MAX_CLIENT_NAME_SIZE];
+	/* The driver state in TX or RX direction */
+	enum usf_state_type usf_state;
+	/* wait for q6 events mechanism */
+	wait_queue_head_t wait;
+	/* IF with q6usm info */
+	struct us_client *usc;
+	/* Q6:USM' Encoder/decoder configuration */
+	struct us_encdec_cfg encdec_cfg;
+	/* Shared buffer (with Q6:USM) size */
+	uint32_t buffer_size;
+	/* Number of the shared buffers (with Q6:USM) */
+	uint32_t buffer_count;
+	/* Shared memory (Cyclic buffer with 1 gap) control */
+	uint32_t new_region;
+	uint32_t prev_region;
+	/* Q6:USM's events handler */
+	void (*cb)(uint32_t, uint32_t, uint32_t *, void *);
+	/* User's update info isn't acceptable */
+	u8 user_upd_info_na;
+};
+
+struct usf_type {
+	/* TX device component configuration & control */
+	struct usf_xx_type usf_tx;
+	/* RX device component configuration & control */
+	struct usf_xx_type usf_rx;
+	/* Index into the opened device container */
+	/* To prevent mutual usage of the same device */
+	uint16_t dev_ind;
+	/* Event types, supported by device */
+	uint16_t event_types;
+	/*  The device is "input" module registered client */
+	struct input_dev *input_if;
+};
+
+/* The MAX number of the supported devices */
+#define MAX_DEVS_NUMBER	1
+
+/* The opened devices container */
+static int s_opened_devs[MAX_DEVS_NUMBER];
+
+static void usf_rx_cb(uint32_t opcode, uint32_t token,
+		      uint32_t *payload, void *priv)
+{
+	struct usf_xx_type *usf_xx = (struct usf_xx_type *) priv;
+
+	if (usf_xx == NULL) {
+		pr_err("%s: the private data is NULL\n", __func__);
+		return;
+	}
+
+	switch (opcode) {
+	case USM_DATA_EVENT_WRITE_DONE:
+		wake_up(&usf_xx->wait);
+		break;
+	default:
+		break;
+	}
+}
+
+static void usf_tx_cb(uint32_t opcode, uint32_t token,
+		      uint32_t *payload, void *priv)
+{
+	struct usf_xx_type *usf_xx = (struct usf_xx_type *) priv;
+
+	if (usf_xx == NULL) {
+		pr_err("%s: the private data is NULL\n", __func__);
+		return;
+	}
+
+	switch (opcode) {
+	case USM_DATA_EVENT_READ_DONE:
+		if (token == USM_WRONG_TOKEN)
+			usf_xx->usf_state = USF_ERROR_STATE;
+		usf_xx->new_region = token;
+		wake_up(&usf_xx->wait);
+		break;
+
+	case APR_BASIC_RSP_RESULT:
+		if (payload[1]) {
+			usf_xx->usf_state = USF_ERROR_STATE;
+			usf_xx->new_region = USM_WRONG_TOKEN;
+			wake_up(&usf_xx->wait);
+		}
+		break;
+
+	default:
+		break;
+	}
+}
+
+static void release_xx(struct usf_xx_type *usf_xx)
+{
+	if (usf_xx != NULL) {
+		if (usf_xx->usc) {
+			q6usm_us_client_free(usf_xx->usc);
+			usf_xx->usc = NULL;
+		}
+
+		if (usf_xx->encdec_cfg.params != NULL) {
+			kfree(usf_xx->encdec_cfg.params);
+			usf_xx->encdec_cfg.params = NULL;
+		}
+	}
+}
+
+static void usf_disable(struct usf_xx_type *usf_xx)
+{
+	if (usf_xx != NULL) {
+		if ((usf_xx->usf_state != USF_IDLE_STATE) &&
+		    (usf_xx->usf_state != USF_OPENED_STATE)) {
+			(void)q6usm_cmd(usf_xx->usc, CMD_CLOSE);
+			usf_xx->usf_state = USF_OPENED_STATE;
+			wake_up(&usf_xx->wait);
+		}
+		release_xx(usf_xx);
+	}
+}
+
+static int config_xx(struct usf_xx_type *usf_xx, struct us_xx_info_type *config)
+{
+	int rc = 0;
+	uint16_t data_map_size = 0;
+
+	if ((usf_xx == NULL) ||
+	    (config == NULL))
+		return -EINVAL;
+
+	data_map_size = sizeof(usf_xx->encdec_cfg.cfg_common.data_map);
+
+	if (config->client_name != NULL) {
+		if (strncpy_from_user(usf_xx->client_name,
+				      config->client_name,
+				      sizeof(usf_xx->client_name) - 1) < 0) {
+			pr_err("%s: get client name failed\n", __func__);
+			return -EINVAL;
+		}
+	}
+
+	pr_info("%s: name=%s; buf_size:%d; dev_id:0x%x; sample_rate:%d\n",
+		__func__, usf_xx->client_name, config->buf_size,
+		config->dev_id, config->sample_rate);
+
+	pr_info("%s: buf_num:%d; format:%d; port_cnt:%d; data_size=%d\n",
+		__func__, config->buf_num, config->stream_format,
+		config->port_cnt, config->params_data_size);
+
+	pr_debug("%s: p_id[0]=%d, p_id[1]=%d, p_id[2]=%d, p_id[3]=%d\n",
+		__func__,
+		config->port_id[0],
+		config->port_id[1],
+		config->port_id[2],
+		config->port_id[3]);
+
+	if (data_map_size < config->port_cnt) {
+		pr_err("%s: number of supported ports:%d < requested:%d\n",
+			__func__,
+			data_map_size,
+			config->port_cnt);
+		return -EINVAL;
+	}
+
+	/* q6usm allocation & configuration */
+	usf_xx->buffer_size = config->buf_size;
+	usf_xx->buffer_count = config->buf_num;
+	usf_xx->encdec_cfg.cfg_common.bits_per_sample =
+				config->bits_per_sample;
+	usf_xx->encdec_cfg.cfg_common.sample_rate = config->sample_rate;
+	/* AFE port e.g. AFE_PORT_ID_SLIMBUS_MULTI_CHAN_1_RX */
+	usf_xx->encdec_cfg.cfg_common.dev_id = config->dev_id;
+
+	usf_xx->encdec_cfg.cfg_common.ch_cfg = config->port_cnt;
+	memcpy((void *)&usf_xx->encdec_cfg.cfg_common.data_map,
+	       (void *)config->port_id,
+	       config->port_cnt);
+	if (rc) {
+		pr_err("%s: ports offsets copy failure\n", __func__);
+		return -EINVAL;
+	}
+
+	usf_xx->encdec_cfg.format_id = config->stream_format;
+	usf_xx->encdec_cfg.params_size = config->params_data_size;
+	usf_xx->user_upd_info_na = 1; /* it's used in US_GET_TX_UPDATE */
+
+	if (config->params_data_size > 0) { /* transparent data copy */
+		usf_xx->encdec_cfg.params = kzalloc(config->params_data_size,
+						    GFP_KERNEL);
+		if (usf_xx->encdec_cfg.params == NULL) {
+			pr_err("%s: params memory alloc[%d] failure\n",
+				__func__,
+				config->params_data_size);
+			return -ENOMEM;
+		}
+		rc = copy_from_user(usf_xx->encdec_cfg.params,
+				    config->params_data,
+				    config->params_data_size);
+		if (rc) {
+			pr_err("%s: transparent data copy failure\n",
+			       __func__);
+			kfree(usf_xx->encdec_cfg.params);
+			usf_xx->encdec_cfg.params = NULL;
+			return -EINVAL;
+		}
+		pr_debug("%s: params_size[%d]; params[%d,%d,%d,%d, %d]\n",
+			 __func__,
+			 config->params_data_size,
+			 usf_xx->encdec_cfg.params[0],
+			 usf_xx->encdec_cfg.params[1],
+			 usf_xx->encdec_cfg.params[2],
+			 usf_xx->encdec_cfg.params[3],
+			 usf_xx->encdec_cfg.params[4]
+			);
+	}
+
+	usf_xx->usc = q6usm_us_client_alloc(usf_xx->cb, (void *)usf_xx);
+	if (!usf_xx->usc) {
+		pr_err("%s: Could not allocate q6usm client\n", __func__);
+		rc = -EFAULT;
+	}
+
+	return rc;
+}
+
+static int register_input_device(struct usf_type *usf_info,
+				 struct us_input_info_type *input_info)
+{
+	int rc = 0;
+	struct input_dev *input_dev = NULL;
+
+	if ((usf_info == NULL) ||
+	    (input_info == NULL) ||
+	    !(input_info->event_types & USF_ALL_EVENTS)) {
+		pr_err("%s: wrong input parameter(s)\n", __func__);
+		return -EINVAL;
+	}
+
+	if (usf_info->input_if != NULL) {
+		pr_err("%s: input_if is already allocated\n", __func__);
+		return -EFAULT;
+	}
+
+	input_dev = input_allocate_device();
+	if (input_dev == NULL) {
+		pr_err("%s: input_allocate_device() failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	/* Common part configuration */
+	input_dev->name = (const char *)(usf_info->usf_tx.client_name);
+	input_dev->phys = NULL;
+	input_dev->id.bustype = BUS_HOST;
+	input_dev->id.vendor  = 0x0001;
+	input_dev->id.product = 0x0001;
+	input_dev->id.version = 0x0001;
+
+	if (input_info->event_types & USF_TSC_EVENT) {
+		/* TSC part configuration */
+		input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+		input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+		input_set_abs_params(input_dev, ABS_X,
+				     input_info->tsc_x_dim[0],
+				     input_info->tsc_x_dim[1],
+				     input_info->tsc_x_fuzz, 0);
+		input_set_abs_params(input_dev, ABS_Y,
+				     input_info->tsc_y_dim[0],
+				     input_info->tsc_y_dim[1],
+				     input_info->tsc_y_fuzz, 0);
+
+		input_set_abs_params(input_dev, ABS_PRESSURE,
+				     input_info->tsc_pressure[0],
+				     input_info->tsc_pressure[1], 0, 0);
+
+	}
+
+	if (input_info->event_types & USF_MOUSE_EVENT) {
+		/* Mouse part configuration */
+		input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+
+		input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+							BIT_MASK(BTN_RIGHT) |
+							BIT_MASK(BTN_MIDDLE);
+		input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+	}
+
+	if (input_info->event_types & USF_KEYBOARD_EVENT) {
+		/* Keyboard part configuration */
+		input_dev->evbit[0] |= BIT_MASK(EV_KEY);
+
+		/* All keys are permitted */
+		memset(input_dev->keybit, 0xff, sizeof(input_dev->keybit));
+	}
+
+	rc = input_register_device(input_dev);
+	if (rc) {
+		pr_err("%s: input_register_device() failed; rc=%d\n",
+		       __func__, rc);
+		input_free_device(input_dev);
+	} else {
+		usf_info->input_if = input_dev;
+		usf_info->event_types = input_info->event_types;
+		pr_info("%s: input device[%s] was registered\n",
+			__func__, input_dev->name);
+	}
+
+	return rc;
+
+}
+
+static void notify_tsc_event(struct input_dev *input_if,
+			     int x, int y, int pressure)
+{
+	if (pressure) {
+		input_report_abs(input_if, ABS_X, x);
+		input_report_abs(input_if, ABS_Y, y);
+		input_report_abs(input_if, ABS_PRESSURE, pressure);
+		input_report_key(input_if, BTN_TOUCH, !!pressure);
+	} else {
+		input_report_abs(input_if, ABS_PRESSURE, 0);
+		input_report_key(input_if, BTN_TOUCH, 0);
+	}
+
+	input_sync(input_if);
+
+	pr_debug("%s: TSC event: x[%d], y[%d], pressure[%d]\n",
+		 __func__, x, y, pressure);
+}
+
+static void notify_mouse_event(struct input_dev *input_if,
+			       struct mouse_event_type *me)
+{
+	if (me == NULL) {
+		pr_err("%s: mouse event is NULL\n", __func__);
+		return;
+	}
+
+	input_report_rel(input_if, REL_X, me->rels[0]);
+	input_report_rel(input_if, REL_Y, me->rels[1]);
+
+	input_report_key(input_if, BTN_LEFT,
+			 me->buttons_states & USF_BUTTON_LEFT_MASK);
+	input_report_key(input_if, BTN_MIDDLE,
+			 me->buttons_states & USF_BUTTON_MIDDLE_MASK);
+	input_report_key(input_if, BTN_RIGHT,
+			 me->buttons_states & USF_BUTTON_RIGHT_MASK);
+
+	input_sync(input_if);
+
+	pr_debug("%s: mouse event: dx[%d], dy[%d], buttons_states[%d]\n",
+		 __func__, me->rels[0], me->rels[1], me->buttons_states);
+}
+
+static void notify_key_event(struct input_dev *input_if,
+			       struct key_event_type *ke)
+{
+	if (ke == NULL) {
+		pr_err("%s: key event is NULL\n", __func__);
+		return;
+	}
+
+	input_report_key(input_if, ke->key, ke->key_state);
+	input_sync(input_if);
+	pr_debug("%s: key event: key[%d], state[%d]\n",
+		 __func__,
+		 ke->key,
+		 ke->key_state);
+
+}
+
+static void handle_input_event(struct usf_type *usf_info,
+			       uint16_t event_counter,
+			       struct usf_event_type *event)
+{
+	struct input_dev *input_if = NULL;
+	uint16_t ind = 0;
+
+	if ((usf_info == NULL) || (usf_info->input_if == NULL) ||
+	    (event == NULL) || (!event_counter)) {
+		return;
+	}
+
+	input_if = usf_info->input_if;
+
+	for (ind = 0; ind < event_counter; ++ind) {
+		event += ind;
+		if (event->event_type & usf_info->event_types) {
+			/* the event is supported */
+			if (event->event_type & USF_TSC_EVENT) {
+				struct point_event_type *pe =
+					&(event->event_data.point_event);
+				if (pe->coordinates_type ==
+				    USF_PIX_COORDINATE) {
+					notify_tsc_event(input_if,
+							 pe->coordinates[0],
+							 pe->coordinates[1],
+							 pe->pressure);
+				} else
+					pr_debug("%s: wrong coord type:%d\n",
+						 __func__,
+						 pe->coordinates_type);
+
+				continue;
+			}
+
+			if (event->event_type & USF_MOUSE_EVENT) {
+				notify_mouse_event(input_if,
+					&(event->event_data.mouse_event));
+				continue;
+			}
+
+			if (event->event_type & USF_KEYBOARD_EVENT) {
+				notify_key_event(input_if,
+					&(event->event_data.key_event));
+				continue;
+			}
+		} /* the event is supported */
+	}
+}
+
+static int usf_start_tx(struct usf_xx_type *usf_xx)
+{
+	int rc = q6usm_run(usf_xx->usc, 0, 0, 0);
+
+	pr_debug("%s: tx: q6usm_run; rc=%d\n", __func__, rc);
+	if (!rc) {
+		/* supply all buffers */
+		rc = q6usm_read(usf_xx->usc,
+				usf_xx->buffer_count);
+		pr_debug("%s: q6usm_read[%d]\n",
+			 __func__, rc);
+
+		if (rc)
+			pr_err("%s: buf read failed",
+			       __func__);
+		else
+			usf_xx->usf_state =
+				USF_WORK_STATE;
+	}
+
+	return rc;
+} /* usf_start_tx */
+
+static int usf_start_rx(struct usf_xx_type *usf_xx)
+{
+	int rc = q6usm_run(usf_xx->usc, 0, 0, 0);
+
+	pr_debug("%s: rx: q6usm_run; rc=%d\n",
+		 __func__, rc);
+	if (!rc)
+		usf_xx->usf_state = USF_WORK_STATE;
+
+	return rc;
+} /* usf_start_rx */
+
+static int usf_set_tx_info(struct usf_type *usf, unsigned long arg)
+{
+	struct us_tx_info_type config_tx;
+	const char *name = NULL;
+	struct usf_xx_type *usf_xx =  &usf->usf_tx;
+	int rc = copy_from_user(&config_tx,
+			    (void *) arg,
+			    sizeof(config_tx));
+
+	if (rc) {
+		pr_err("%s: copy error[%d]\n",
+			__func__, rc);
+		return -EINVAL;
+	}
+
+	name = config_tx.us_xx_info.client_name;
+
+	usf_xx->new_region = USM_UNDEF_TOKEN;
+	usf_xx->prev_region = USM_UNDEF_TOKEN;
+	usf_xx->cb = usf_tx_cb;
+
+	init_waitqueue_head(&usf_xx->wait);
+
+	if (name != NULL) {
+		int res = strncpy_from_user(
+			usf_xx->client_name,
+			name,
+			sizeof(usf_xx->client_name)-1);
+		if (res < 0) {
+			pr_err("%s: get client name failed\n",
+			       __func__);
+			return -EINVAL;
+		}
+	}
+
+	rc = config_xx(usf_xx, &config_tx.us_xx_info);
+	if (rc)
+		return rc;
+
+	rc = q6usm_open_read(usf_xx->usc,
+			     usf_xx->encdec_cfg.format_id);
+	if (rc)
+		return rc;
+
+	rc = q6usm_us_client_buf_alloc(OUT, usf_xx->usc,
+				       usf_xx->buffer_size,
+				       usf_xx->buffer_count);
+	if (rc)
+		return rc;
+
+	rc = q6usm_enc_cfg_blk(usf_xx->usc,
+			       &usf_xx->encdec_cfg);
+	if (!rc) {
+		rc = register_input_device(usf,
+					   &config_tx.input_info);
+		if (!rc)
+			usf_xx->usf_state = USF_CONFIGURED_STATE;
+	}
+
+	return rc;
+} /* usf_set_tx_info */
+
+static int usf_set_rx_info(struct usf_type *usf, unsigned long arg)
+{
+	struct us_rx_info_type config_rx;
+	struct usf_xx_type *usf_xx =  &usf->usf_rx;
+	int rc = copy_from_user(&config_rx,
+			    (void *) arg,
+			    sizeof(config_rx));
+
+	if (rc) {
+		pr_err("%s: copy_from_user() failed[%d]\n",
+			__func__, rc);
+		return -EINVAL;
+	}
+
+	usf_xx->new_region = USM_UNDEF_TOKEN;
+	usf_xx->prev_region = USM_UNDEF_TOKEN;
+
+	usf_xx->cb = usf_rx_cb;
+
+	rc = config_xx(usf_xx, &config_rx.us_xx_info);
+	if (rc)
+		return rc;
+
+	rc = q6usm_open_write(usf_xx->usc,
+			      usf_xx->encdec_cfg.format_id);
+	if (rc)
+		return rc;
+
+	if (usf_xx->buffer_size && usf_xx->buffer_count) {
+		rc = q6usm_us_client_buf_alloc(
+					IN,
+					usf_xx->usc,
+					usf_xx->buffer_size,
+					usf_xx->buffer_count);
+		if (rc)
+			return rc;
+	}
+
+	rc = q6usm_dec_cfg_blk(usf_xx->usc,
+			       &usf_xx->encdec_cfg);
+	if (!rc) {
+		init_waitqueue_head(&usf_xx->wait);
+		usf_xx->usf_state = USF_CONFIGURED_STATE;
+	}
+
+	return rc;
+} /* usf_set_rx_info */
+
+
+static int usf_get_tx_update(struct usf_type *usf, unsigned long arg)
+{
+	struct us_tx_update_info_type upd_tx_info;
+	unsigned long prev_jiffies = 0;
+	struct usf_xx_type *usf_xx =  &usf->usf_tx;
+	int rc = copy_from_user(&upd_tx_info, (void *) arg,
+			    sizeof(upd_tx_info));
+
+	if (rc) {
+		pr_err("%s: get_update: copy_from_user() failed[%d]\n",
+		       __func__, rc);
+		return -EINVAL;
+	}
+
+	if (!usf_xx->user_upd_info_na) {
+		handle_input_event(usf,
+				   upd_tx_info.event_counter,
+				   upd_tx_info.event);
+
+		/* Release available regions */
+		rc = q6usm_read(usf_xx->usc,
+				upd_tx_info.free_region);
+		if (rc)
+			return rc;
+	} else
+		usf_xx->user_upd_info_na = 0;
+
+	/* Get data ready regions */
+	prev_jiffies = jiffies;
+	rc = wait_event_timeout(usf_xx->wait,
+				(usf_xx->prev_region !=
+				 usf_xx->new_region) ||
+				(usf_xx->usf_state !=
+				 USF_WORK_STATE),
+				USF_TIMEOUT_JIFFIES);
+
+	if (!rc) {
+		pr_debug("%s: timeout. prev_j=%lu; j=%lu\n",
+			__func__, prev_jiffies, jiffies);
+		pr_debug("%s: timeout. prev=%d; new=%d\n",
+			__func__, usf_xx->prev_region,
+			usf_xx->new_region);
+		pr_debug("%s: timeout. free_region=%d;\n",
+			__func__, upd_tx_info.free_region);
+		if (usf_xx->prev_region ==
+		    usf_xx->new_region) {
+			pr_err("%s:read data: timeout\n",
+			       __func__);
+			return -ETIME;
+		}
+	}
+
+	if (usf_xx->usf_state != USF_WORK_STATE) {
+		pr_err("%s: TX device is in not work state[%d]\n",
+		       __func__, usf_xx->usf_state);
+		return -EINTR;
+	}
+
+	upd_tx_info.ready_region = usf_xx->new_region;
+	rc = copy_to_user((void __user *)arg, &upd_tx_info,
+			  sizeof(upd_tx_info));
+	if (upd_tx_info.ready_region == USM_WRONG_TOKEN) {
+		pr_err("%s: TX path corrupted; prev=%d\n",
+		       __func__, usf_xx->prev_region);
+		rc = -EIO;
+	}
+	usf_xx->prev_region = upd_tx_info.ready_region;
+
+	return rc;
+} /* usf_get_tx_update */
+
+static int usf_set_rx_update(struct usf_xx_type *usf_xx, unsigned long arg)
+{
+	struct us_rx_update_info_type upd_rx_info;
+	int rc = copy_from_user(&upd_rx_info, (void *) arg,
+			    sizeof(upd_rx_info));
+
+	if (rc) {
+		pr_err("%s: get_update: copy_from_user() failed[%d]\n",
+		       __func__, rc);
+		return -EINVAL;
+	}
+
+	/* Send available data regions */
+	if (upd_rx_info.ready_region !=
+	    usf_xx->buffer_count) {
+		rc = q6usm_write(
+			usf_xx->usc,
+			upd_rx_info.ready_region);
+		if (rc)
+			return rc;
+	}
+
+	/* Get free regions */
+	rc = wait_event_timeout(
+		usf_xx->wait,
+		!q6usm_is_write_buf_full(
+			usf_xx->usc,
+			&upd_rx_info.free_region) ||
+		(usf_xx->usf_state == USF_IDLE_STATE),
+		USF_TIMEOUT_JIFFIES);
+
+	if (!rc) {
+		rc = -ETIME;
+		pr_err("%s:timeout. wait for write buf not full\n",
+		       __func__);
+	} else {
+		if (usf_xx->usf_state !=
+		    USF_WORK_STATE) {
+			pr_err("%s: RX: state[%d]\n",
+			       __func__,
+			       usf_xx->usf_state);
+			rc = -EINTR;
+		} else
+			rc = copy_to_user(
+				(void __user *)arg,
+				&upd_rx_info,
+				sizeof(upd_rx_info));
+	}
+
+	return rc;
+} /* usf_set_rx_update */
+
+static int usf_stop_tx(struct usf_type *usf)
+{
+	struct usf_xx_type *usf_xx =  &usf->usf_tx;
+
+	if (usf->input_if != NULL) {
+		input_unregister_device(usf->input_if);
+		usf->input_if = NULL;
+		pr_info("%s input_unregister_device",
+			__func__);
+	}
+	usf_disable(usf_xx);
+
+	return 0;
+} /* usf_stop_tx */
+
+static long usf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	int rc = 0;
+	struct usf_type *usf = file->private_data;
+	struct usf_xx_type *usf_xx = NULL;
+
+	switch (cmd) {
+	case US_START_TX: {
+		usf_xx = &usf->usf_tx;
+		if (usf_xx->usf_state == USF_CONFIGURED_STATE)
+			rc = usf_start_tx(usf_xx);
+		else {
+			pr_err("%s: start_tx: wrong state[%d]\n",
+			       __func__,
+			       usf_xx->usf_state);
+			return -EBADFD;
+		}
+		break;
+	}
+
+	case US_START_RX: {
+		usf_xx = &usf->usf_rx;
+		if (usf_xx->usf_state == USF_CONFIGURED_STATE)
+			rc = usf_start_rx(usf_xx);
+		else {
+			pr_err("%s: start_rx: wrong state[%d]\n",
+				__func__,
+				usf_xx->usf_state);
+			return -EBADFD;
+		}
+		break;
+	}
+
+	case US_SET_TX_INFO: {
+		usf_xx = &usf->usf_tx;
+		if (usf_xx->usf_state == USF_OPENED_STATE)
+			rc = usf_set_tx_info(usf, arg);
+		else {
+			pr_err("%s: set_tx_info: wrong state[%d]\n",
+			       __func__,
+			       usf_xx->usf_state);
+			return -EBADFD;
+		}
+
+		break;
+	} /* US_SET_TX_INFO */
+
+	case US_SET_RX_INFO: {
+		usf_xx = &usf->usf_rx;
+		if (usf_xx->usf_state == USF_OPENED_STATE)
+			rc = usf_set_rx_info(usf, arg);
+		else {
+			pr_err("%s: set_rx_info: wrong state[%d]\n",
+				__func__,
+				usf_xx->usf_state);
+			return -EBADFD;
+		}
+
+		break;
+	} /* US_SET_RX_INFO */
+
+	case US_GET_TX_UPDATE: {
+		struct usf_xx_type *usf_xx = &usf->usf_tx;
+		if (usf_xx->usf_state == USF_WORK_STATE)
+			rc = usf_get_tx_update(usf, arg);
+		else {
+			pr_err("%s: get_tx_update: wrong state[%d]\n", __func__,
+			       usf_xx->usf_state);
+			rc = -EBADFD;
+		}
+		break;
+	} /* US_GET_TX_UPDATE */
+
+	case US_SET_RX_UPDATE: {
+		struct usf_xx_type *usf_xx = &usf->usf_rx;
+		if (usf_xx->usf_state == USF_WORK_STATE)
+			rc = usf_set_rx_update(usf_xx, arg);
+		else {
+			pr_err("%s: set_rx_update: wrong state[%d]\n",
+			       __func__,
+			       usf_xx->usf_state);
+			rc = -EBADFD;
+		}
+		break;
+	} /* US_SET_RX_UPDATE */
+
+	case US_STOP_TX: {
+		usf_xx = &usf->usf_tx;
+		if (usf_xx->usf_state == USF_WORK_STATE)
+			rc = usf_stop_tx(usf);
+		else {
+			pr_err("%s: stop_tx: wrong state[%d]\n",
+			       __func__,
+			       usf_xx->usf_state);
+			return -EBADFD;
+		}
+		break;
+	} /* US_STOP_TX */
+
+	case US_STOP_RX: {
+		usf_xx = &usf->usf_rx;
+		if (usf_xx->usf_state == USF_WORK_STATE)
+			usf_disable(usf_xx);
+		else {
+			pr_err("%s: stop_rx: wrong state[%d]\n",
+			       __func__,
+			       usf_xx->usf_state);
+			return -EBADFD;
+		}
+		break;
+	} /* US_STOP_RX */
+
+	default:
+		rc = -EINVAL;
+		break;
+	}
+
+	if (rc &&
+	    ((cmd == US_SET_TX_INFO) ||
+	     (cmd == US_SET_RX_INFO)))
+		release_xx(usf_xx);
+
+	return rc;
+} /* usf_ioctl */
+
+static int usf_mmap(struct file *file, struct vm_area_struct *vms)
+{
+	struct usf_type *usf = file->private_data;
+	int dir = OUT;
+	struct usf_xx_type *usf_xx = &usf->usf_tx;
+
+	if (vms->vm_flags & USF_VM_WRITE) { /* RX buf mapping */
+		dir = IN;
+		usf_xx = &usf->usf_rx;
+	}
+
+	return q6usm_get_virtual_address(dir, usf_xx->usc, vms);
+}
+
+static uint16_t add_opened_dev(int minor)
+{
+	uint16_t ind = 0;
+
+	for (ind = 0; ind < MAX_DEVS_NUMBER; ++ind) {
+		if (minor == s_opened_devs[ind]) {
+			pr_err("%s: device %d is already opened\n",
+			       __func__, minor);
+			return USF_UNDEF_DEV_ID;
+		}
+
+		if (s_opened_devs[ind] == 0) {
+			s_opened_devs[ind] = minor;
+			pr_info("%s: device %d is added; ind=%d\n",
+				__func__, minor, ind);
+			return ind;
+		}
+	}
+
+	pr_err("%s: there is no place for device %d\n",
+	       __func__, minor);
+	return USF_UNDEF_DEV_ID;
+}
+
+static int usf_open(struct inode *inode, struct file *file)
+{
+	struct usf_type *usf =  NULL;
+	uint16_t dev_ind = 0;
+	int minor = MINOR(inode->i_rdev);
+
+	dev_ind = add_opened_dev(minor);
+	if (dev_ind == USF_UNDEF_DEV_ID)
+		return -EBUSY;
+
+	usf = kzalloc(sizeof(struct usf_type), GFP_KERNEL);
+	if (usf == NULL) {
+		pr_err("%s:usf allocation failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	file->private_data = usf;
+	usf->dev_ind = dev_ind;
+
+	usf->usf_tx.usf_state = USF_OPENED_STATE;
+	usf->usf_rx.usf_state = USF_OPENED_STATE;
+
+	pr_info("%s:usf in open\n", __func__);
+	return 0;
+}
+
+
+static int usf_release(struct inode *inode, struct file *file)
+{
+	struct usf_type *usf = file->private_data;
+
+	pr_info("%s: release entry\n", __func__);
+
+	if (usf->input_if != NULL) {
+		input_unregister_device(usf->input_if);
+		usf->input_if = NULL;
+		pr_info("%s input_unregister_device\n",  __func__);
+	}
+
+	usf_disable(&usf->usf_tx);
+	usf_disable(&usf->usf_rx);
+
+	s_opened_devs[usf->dev_ind] = 0;
+
+	kfree(usf);
+	pr_info("%s: release exit\n", __func__);
+	return 0;
+}
+
+static const struct file_operations usf_fops = {
+	.owner                  = THIS_MODULE,
+	.open                   = usf_open,
+	.release                = usf_release,
+	.unlocked_ioctl = usf_ioctl,
+	.mmap                   = usf_mmap,
+};
+
+struct miscdevice usf_misc[MAX_DEVS_NUMBER] = {
+	{
+		.minor  = MISC_DYNAMIC_MINOR,
+		.name   = "usf1",
+		.fops   = &usf_fops,
+	},
+};
+
+static int __init usf_init(void)
+{
+	int rc = 0;
+	uint16_t ind = 0;
+
+	pr_info("%s: USF SW version %s.\n", __func__, DRV_VERSION);
+	pr_info("%s: Max %d devs registration\n", __func__, MAX_DEVS_NUMBER);
+
+	for (ind = 0; ind < MAX_DEVS_NUMBER; ++ind) {
+		rc = misc_register(&usf_misc[ind]);
+		if (rc) {
+			pr_err("%s: misc_register() failed ind=%d; rc = %d\n",
+			       __func__, ind, rc);
+			break;
+		}
+	}
+
+	return rc;
+}
+
+device_initcall(usf_init);
+
+MODULE_DESCRIPTION("Ultrasound framework driver");
+MODULE_VERSION(DRV_VERSION);
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index 206dfd2..96a4563 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.c
@@ -225,6 +225,9 @@
 	/* 8060A ID */
 	[124] = MSM_CPU_8960,
 
+	/* Copper IDs */
+	[126] = MSM_CPU_COPPER,
+
 	/* Uninitialized IDs are not known to run Linux.
 	   MSM_CPU_UNKNOWN is set to 0 to ensure these IDs are
 	   considered as unknown CPU. */
@@ -591,6 +594,8 @@
 		dummy_socinfo.id = 109;
 	else if (machine_is_msm9615_mtp() || machine_is_msm9615_cdp())
 		dummy_socinfo.id = 104;
+	else if (early_machine_is_copper())
+		dummy_socinfo.id = 126;
 	return (void *) &dummy_socinfo;
 }
 
diff --git a/arch/arm/mach-msm/subsystem_map.c b/arch/arm/mach-msm/subsystem_map.c
index 41d8072..11fe26c 100644
--- a/arch/arm/mach-msm/subsystem_map.c
+++ b/arch/arm/mach-msm/subsystem_map.c
@@ -208,58 +208,18 @@
 	return 0;
 }
 
-static unsigned long allocate_iova_address(unsigned long size,
-					int subsys_id,
-					unsigned long align)
-{
-	struct mem_pool *pool = msm_subsystem_get_pool(subsys_id);
-	unsigned long iova;
-
-	iova = gen_pool_alloc_aligned(pool->gpool, size, ilog2(align));
-	if (iova)
-		pool->free -= size;
-
-	return iova;
-}
-
-static void free_iova_address(unsigned long iova,
-			unsigned long size,
-			int subsys_id)
-{
-	struct mem_pool *pool = msm_subsystem_get_pool(subsys_id);
-
-	pool->free += size;
-	gen_pool_free(pool->gpool, iova, size);
-}
-
-static int subsys_validate(int subsys_id)
-{
-	struct mem_pool *pool;
-	struct iommu_domain *subsys_domain;
-
-	if (!msm_subsystem_check_id(subsys_id)) {
-		WARN(1, "subsystem id is not valid. Caller should check this.");
-		return 0;
-	}
-
-	pool = msm_subsystem_get_pool(subsys_id);
-	subsys_domain = msm_subsystem_get_domain(subsys_id);
-
-	return subsys_domain && pool && pool->gpool;
-}
-
 phys_addr_t msm_subsystem_check_iova_mapping(int subsys_id, unsigned long iova)
 {
 	struct iommu_domain *subsys_domain;
 
-	if (!subsys_validate(subsys_id))
+	if (!msm_use_iommu())
 		/*
-		 * If the subsystem is not valid, assume a phys = iova
-		 * mapping. Just return the iova in this case.
+		 * If there is no iommu, Just return the iova in this case.
 		 */
 		return iova;
 
-	subsys_domain = msm_subsystem_get_domain(subsys_id);
+	subsys_domain = msm_get_iommu_domain(msm_subsystem_get_domain_no
+								(subsys_id));
 
 	return iommu_iova_to_phys(subsys_domain, iova);
 }
@@ -355,15 +315,29 @@
 		min_align = flags & ~(SZ_4K - 1);
 
 		for (i = 0; i < nsubsys; i++) {
-			if (!subsys_validate(subsys_ids[i])) {
+			unsigned int domain_no, partition_no;
+
+			if (!msm_use_iommu()) {
 				buf->iova[i] = phys;
 				continue;
 			}
 
-			d = msm_subsystem_get_domain(subsys_ids[i]);
+			d = msm_get_iommu_domain(
+				msm_subsystem_get_domain_no(subsys_ids[i]));
 
-			iova_start = allocate_iova_address(length,
-						subsys_ids[i],
+			if (!d) {
+				pr_err("%s: could not get domain for subsystem"
+					" %d\n", __func__, subsys_ids[i]);
+				continue;
+			}
+
+			domain_no = msm_subsystem_get_domain_no(subsys_ids[i]);
+			partition_no = msm_subsystem_get_partition_no(
+								subsys_ids[i]);
+
+			iova_start = msm_allocate_iova_address(domain_no,
+						partition_no,
+						length,
 						max(min_align, SZ_4K));
 
 			if (!iova_start) {
@@ -410,19 +384,26 @@
 		iommu_unmap(d, temp_va, get_order(SZ_4K));
 outdomain:
 	if (flags & MSM_SUBSYSTEM_MAP_IOVA) {
+		/* Unmap the rest of the current domain, i */
 		for (j -= SZ_4K, temp_va -= SZ_4K;
 			j > 0; temp_va -= SZ_4K, j -= SZ_4K)
 			iommu_unmap(d, temp_va, get_order(SZ_4K));
 
+		/* Unmap all the other domains */
 		for (i--; i >= 0; i--) {
-			if (!subsys_validate(subsys_ids[i]))
+			unsigned int domain_no, partition_no;
+			if (!msm_use_iommu())
 				continue;
+			domain_no = msm_subsystem_get_domain_no(subsys_ids[i]);
+			partition_no = msm_subsystem_get_partition_no(
+								subsys_ids[i]);
 
 			temp_va = buf->iova[i];
 			for (j = length; j > 0; j -= SZ_4K,
 						temp_va += SZ_4K)
 				iommu_unmap(d, temp_va, get_order(SZ_4K));
-			free_iova_address(buf->iova[i], length, subsys_ids[i]);
+			msm_free_iova_address(buf->iova[i], domain_no,
+					partition_no, length);
 		}
 
 		kfree(buf->iova);
@@ -464,25 +445,32 @@
 	}
 
 	if (buf->iova) {
-		for (i = 0; i < node->nsubsys; i++) {
-			struct iommu_domain *subsys_domain;
+		if (msm_use_iommu())
+			for (i = 0; i < node->nsubsys; i++) {
+				struct iommu_domain *subsys_domain;
+				unsigned int domain_no, partition_no;
 
-			if (!subsys_validate(node->subsystems[i]))
-				continue;
+				subsys_domain = msm_get_iommu_domain(
+						msm_subsystem_get_domain_no(
+						node->subsystems[i]));
 
-			subsys_domain = msm_subsystem_get_domain(
+				domain_no = msm_subsystem_get_domain_no(
 							node->subsystems[i]);
-			temp_va = buf->iova[i];
-			for (j = node->length; j > 0; j -= SZ_4K,
-				temp_va += SZ_4K) {
-				ret = iommu_unmap(subsys_domain, temp_va,
+				partition_no = msm_subsystem_get_partition_no(
+							node->subsystems[i]);
+
+				temp_va = buf->iova[i];
+				for (j = node->length; j > 0; j -= SZ_4K,
+					temp_va += SZ_4K) {
+					ret = iommu_unmap(subsys_domain,
+							temp_va,
 							get_order(SZ_4K));
-				WARN(ret, "iommu_unmap returned a non-zero"
-						" value.\n");
+					WARN(ret, "iommu_unmap returned a "
+						" non-zero value.\n");
+				}
+				msm_free_iova_address(buf->iova[i], domain_no,
+						partition_no, node->length);
 			}
-			free_iova_address(buf->iova[i], node->length,
-							node->subsystems[i]);
-		}
 		kfree(buf->iova);
 
 	}
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index d9488ec..fd9049f 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -939,12 +939,19 @@
 
 static DEFINE_CLOCK_DATA(cd);
 
+/*
+ * Store the most recent timestamp read from hardware
+ * in last_ns. This is useful for debugging crashes.
+ */
+static u64 last_ns;
+
 unsigned long long notrace sched_clock(void)
 {
 	struct msm_clock *clock = &msm_clocks[msm_global_timer];
 	struct clocksource *cs = &clock->clocksource;
 	u32 cyc = cs->read(cs);
-	return cyc_to_sched_clock(&cd, cyc, ((u32)~0 >> clock->shift));
+	last_ns = cyc_to_sched_clock(&cd, cyc, ((u32)~0 >> clock->shift));
+	return last_ns;
 }
 
 static void notrace msm_update_sched_clock(void)
@@ -1015,6 +1022,7 @@
 	} else {
 		WARN_ON("Timer running on unknown hardware. Configure this! "
 			"Assuming default configuration.\n");
+		global_timer_offset = MSM_TMR0_BASE - MSM_TMR_BASE;
 		dgt->freq = 6750000;
 	}
 
diff --git a/drivers/char/msm_rotator.c b/drivers/char/msm_rotator.c
index bb31b6a..696a7bd 100644
--- a/drivers/char/msm_rotator.c
+++ b/drivers/char/msm_rotator.c
@@ -29,6 +29,7 @@
 #include <linux/file.h>
 #include <linux/major.h>
 #include <linux/regulator/consumer.h>
+#include <linux/ion.h>
 
 #define DRIVER_NAME "msm_rotator"
 
@@ -123,6 +124,7 @@
 	struct mutex imem_lock;
 	int imem_owner;
 	wait_queue_head_t wq;
+	struct ion_client *client;
 };
 
 #define COMPONENT_5BITS 1
@@ -709,57 +711,82 @@
 	return 0;
 }
 
-static int get_img(int memory_id, unsigned long *start, unsigned long *len,
-		struct file **pp_file)
+static int get_img(struct msmfb_data *fbd, unsigned long *start,
+	unsigned long *len, struct file **p_file, struct ion_handle **p_ihdl)
 {
 	int ret = 0;
 #ifdef CONFIG_FB
-	struct file *file;
+	struct file *file = NULL;
 	int put_needed, fb_num;
 #endif
 #ifdef CONFIG_ANDROID_PMEM
 	unsigned long vstart;
 #endif
 
-#ifdef CONFIG_ANDROID_PMEM
-	if (!get_pmem_file(memory_id, start, &vstart, len, pp_file))
-		return 0;
-#endif
 #ifdef CONFIG_FB
-	file = fget_light(memory_id, &put_needed);
-	if (file == NULL)
-		return -1;
+	if (fbd->flags & MDP_MEMORY_ID_TYPE_FB) {
+		file = fget_light(fbd->memory_id, &put_needed);
+		if (file == NULL)
+			return -EINVAL;
 
-	if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
-		fb_num = MINOR(file->f_dentry->d_inode->i_rdev);
-		if (get_fb_phys_info(start, len, fb_num))
+		if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
+			fb_num = MINOR(file->f_dentry->d_inode->i_rdev);
+			if (get_fb_phys_info(start, len, fb_num))
+				ret = -1;
+			else
+				*p_file = file;
+		} else
 			ret = -1;
-		else
-			*pp_file = file;
-	} else
-		ret = -1;
-	if (ret)
-		fput_light(file, put_needed);
+		if (ret)
+			fput_light(file, put_needed);
+		return ret;
+	}
 #endif
-	return ret;
+
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	*p_ihdl = ion_import_fd(msm_rotator_dev->client,
+		fbd->memory_id);
+	if (IS_ERR_OR_NULL(*p_ihdl))
+		return PTR_ERR(*p_ihdl);
+	if (!ion_phys(msm_rotator_dev->client, *p_ihdl, start,
+		(size_t *) len))
+		return 0;
+	else
+		return -ENOMEM;
+#endif
+#ifdef CONFIG_ANDROID_PMEM
+	if (!get_pmem_file(fbd->memory_id, start, &vstart, len, p_file))
+		return 0;
+	else
+		return -ENOMEM;
+#endif
+
 }
 
+static void put_img(struct file *p_file, struct ion_handle *p_ihdl)
+{
+#ifdef CONFIG_ANDROID_PMEM
+	if (p_file != NULL)
+		put_pmem_file(p_file);
+#endif
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	if (!IS_ERR_OR_NULL(p_ihdl))
+		ion_free(msm_rotator_dev->client, p_ihdl);
+#endif
+}
 static int msm_rotator_do_rotate(unsigned long arg)
 {
-	int rc = 0;
-	unsigned int status;
+	unsigned int status, format;
 	struct msm_rotator_data_info info;
 	unsigned int in_paddr, out_paddr;
 	unsigned long src_len, dst_len;
-	struct file *src_file = 0;
-	struct file *dst_file = 0;
-	int use_imem = 0;
-	int s;
-	struct file *src_chroma_file = 0;
-	struct file *dst_chroma_file = 0;
+	int use_imem = 0, rc = 0, s;
+	struct file *srcp0_file = NULL, *dstp0_file = NULL;
+	struct file *srcp1_file = NULL, *dstp1_file = NULL;
+	struct ion_handle *srcp0_ihdl = NULL, *dstp0_ihdl = NULL;
+	struct ion_handle *srcp1_ihdl = NULL, *dstp1_ihdl = NULL;
 	unsigned int in_chroma_paddr = 0, out_chroma_paddr = 0;
 	unsigned int in_chroma2_paddr = 0;
-	uint32_t format;
 	struct msm_rotator_img_info *img_info;
 	struct msm_rotator_mem_planes src_planes, dst_planes;
 
@@ -808,16 +835,16 @@
 		goto do_rotate_unlock_mutex;
 	}
 
-	rc = get_img(info.src.memory_id, (unsigned long *)&in_paddr,
-			(unsigned long *)&src_len, &src_file);
+	rc = get_img(&info.src, (unsigned long *)&in_paddr,
+			(unsigned long *)&src_len, &srcp0_file, &srcp0_ihdl);
 	if (rc) {
 		pr_err("%s: in get_img() failed id=0x%08x\n",
 			DRIVER_NAME, info.src.memory_id);
 		goto do_rotate_unlock_mutex;
 	}
 
-	rc = get_img(info.dst.memory_id, (unsigned long *)&out_paddr,
-			(unsigned long *)&dst_len, &dst_file);
+	rc = get_img(&info.dst, (unsigned long *)&out_paddr,
+			(unsigned long *)&dst_len, &dstp0_file, &dstp0_ihdl);
 	if (rc) {
 		pr_err("%s: out get_img() failed id=0x%08x\n",
 		       DRIVER_NAME, info.dst.memory_id);
@@ -845,18 +872,20 @@
 			goto do_rotate_unlock_mutex;
 		}
 
-		rc = get_img(info.src_chroma.memory_id,
+		rc = get_img(&info.src_chroma,
 				(unsigned long *)&in_chroma_paddr,
-				(unsigned long *)&src_len, &src_chroma_file);
+				(unsigned long *)&src_len, &srcp1_file,
+				&srcp1_ihdl);
 		if (rc) {
 			pr_err("%s: in chroma get_img() failed id=0x%08x\n",
 				DRIVER_NAME, info.src_chroma.memory_id);
 			goto do_rotate_unlock_mutex;
 		}
 
-		rc = get_img(info.dst_chroma.memory_id,
+		rc = get_img(&info.dst_chroma,
 				(unsigned long *)&out_chroma_paddr,
-				(unsigned long *)&dst_len, &dst_chroma_file);
+				(unsigned long *)&dst_len, &dstp1_file,
+				&dstp1_ihdl);
 		if (rc) {
 			pr_err("%s: out chroma get_img() failed id=0x%08x\n",
 				DRIVER_NAME, info.dst_chroma.memory_id);
@@ -1019,14 +1048,10 @@
 #endif
 	schedule_delayed_work(&msm_rotator_dev->rot_clk_work, HZ);
 do_rotate_unlock_mutex:
-	if (dst_chroma_file)
-		put_pmem_file(dst_chroma_file);
-	if (src_chroma_file)
-		put_pmem_file(src_chroma_file);
-	if (dst_file)
-		put_pmem_file(dst_file);
-	if (src_file)
-		put_pmem_file(src_file);
+	put_img(dstp1_file, dstp1_ihdl);
+	put_img(srcp1_file, srcp1_ihdl);
+	put_img(dstp0_file, dstp0_ihdl);
+	put_img(srcp0_file, srcp0_ihdl);
 	mutex_unlock(&msm_rotator_dev->rotator_lock);
 	dev_dbg(msm_rotator_dev->device, "%s() returning rc = %d\n",
 		__func__, rc);
@@ -1361,7 +1386,9 @@
 			  msm_rotator_rot_clk_work_f);
 
 	mutex_init(&msm_rotator_dev->rotator_lock);
-
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	msm_rotator_dev->client = msm_ion_client_create(-1, pdev->name);
+#endif
 	platform_set_drvdata(pdev, msm_rotator_dev);
 
 
@@ -1387,9 +1414,9 @@
 	if (msm_rotator_dev->imem_clk)
 		clk_disable(msm_rotator_dev->imem_clk);
 #endif
-	if (ver != pdata->hardware_version_number) {
+	if (ver != pdata->hardware_version_number)
 		pr_info("%s: invalid HW version\n", DRIVER_NAME);
-	}
+
 	msm_rotator_dev->irq = platform_get_irq(pdev, 0);
 	if (msm_rotator_dev->irq < 0) {
 		printk(KERN_ALERT "%s: could not get IORESOURCE_IRQ\n",
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index b13190d..0693f46 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -1080,6 +1080,7 @@
 {
 	long status = 0;
 	uint io = 1;
+	static uint io_cnt;
 	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
 	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
 
@@ -1097,12 +1098,9 @@
 		goto done;
 	}
 	if (!kgsl_check_timestamp(device, timestamp)) {
-		if (pwr->active_pwrlevel) {
-			int low_pwrlevel = pwr->num_pwrlevels -
-					KGSL_PWRLEVEL_LOW_OFFSET;
-			if (pwr->active_pwrlevel == low_pwrlevel)
-				io = 0;
-		}
+		io_cnt = (io_cnt + 1) % 100;
+		if (io_cnt < pwr->pwrlevels[pwr->active_pwrlevel].io_fraction)
+			io = 0;
 		mutex_unlock(&device->mutex);
 		/* We need to make sure that the process is placed in wait-q
 		 * before its condition is called */
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index c6fceaa..e84d473 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -348,6 +348,12 @@
 			KGSL_PWR_WARN(device, "state -> SUSPEND, device %d\n",
 				device->id);
 			break;
+		case KGSL_STATE_SLUMBER:
+			INIT_COMPLETION(device->hwaccess_gate);
+			device->state = KGSL_STATE_SUSPEND;
+			KGSL_PWR_WARN(device, "state -> SUSPEND, device %d\n",
+				device->id);
+			break;
 		default:
 			KGSL_PWR_ERR(device, "suspend fail, device %d\n",
 					device->id);
@@ -374,28 +380,16 @@
 	KGSL_PWR_WARN(device, "resume start\n");
 	mutex_lock(&device->mutex);
 	if (device->state == KGSL_STATE_SUSPEND) {
-		device->requested_state = KGSL_STATE_ACTIVE;
-		kgsl_pwrctrl_pwrlevel_change(device, KGSL_PWRLEVEL_NOMINAL);
-		status = device->ftbl->start(device, 0);
-		if (status == 0) {
-			device->state = KGSL_STATE_ACTIVE;
-			KGSL_PWR_WARN(device,
-					"state -> ACTIVE, device %d\n",
-					device->id);
-		} else {
-			KGSL_PWR_ERR(device,
-					"resume failed, device %d\n",
-					device->id);
-			device->state = KGSL_STATE_INIT;
-			goto end;
-		}
+		device->state = KGSL_STATE_SLUMBER;
+		status = 0;
+		KGSL_PWR_WARN(device,
+				"state -> SLUMBER, device %d\n",
+				device->id);
 		complete_all(&device->hwaccess_gate);
 	}
 	device->requested_state = KGSL_STATE_NONE;
 
-end:
 	mutex_unlock(&device->mutex);
-	kgsl_check_idle(device);
 	KGSL_PWR_WARN(device, "resume end\n");
 	return status;
 }
@@ -436,9 +430,12 @@
 {
 	struct kgsl_device *device = container_of(h,
 					struct kgsl_device, display_off);
+	KGSL_PWR_WARN(device, "early suspend start\n");
 	mutex_lock(&device->mutex);
-	kgsl_pwrctrl_pwrlevel_change(device, KGSL_PWRLEVEL_NOMINAL);
+	device->requested_state = KGSL_STATE_SLUMBER;
+	kgsl_pwrctrl_sleep(device);
 	mutex_unlock(&device->mutex);
+	KGSL_PWR_WARN(device, "early suspend end\n");
 }
 EXPORT_SYMBOL(kgsl_early_suspend_driver);
 
@@ -461,9 +458,13 @@
 {
 	struct kgsl_device *device = container_of(h,
 					struct kgsl_device, display_off);
+	KGSL_PWR_WARN(device, "late resume start\n");
 	mutex_lock(&device->mutex);
-	kgsl_pwrctrl_pwrlevel_change(device, KGSL_PWRLEVEL_TURBO);
+	kgsl_pwrctrl_wake(device);
+	device->pwrctrl.restore_slumber = 0;
 	mutex_unlock(&device->mutex);
+	kgsl_check_idle(device);
+	KGSL_PWR_WARN(device, "late resume end\n");
 }
 EXPORT_SYMBOL(kgsl_late_resume_driver);
 
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index e261b84..6ae9258 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -46,6 +46,7 @@
 #define KGSL_STATE_SUSPEND	0x00000010
 #define KGSL_STATE_HUNG		0x00000020
 #define KGSL_STATE_DUMP_AND_RECOVER	0x00000040
+#define KGSL_STATE_SLUMBER	0x00000080
 
 #define KGSL_GRAPHICS_MEMORY_LOW_WATERMARK  0x1000000
 
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 343a39a..64397e0 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -479,6 +479,8 @@
 					   gpu_freq) : 0;
 		pwr->pwrlevels[i].bus_freq =
 			pdata_pwr->pwrlevel[i].bus_freq;
+		pwr->pwrlevels[i].io_fraction =
+			pdata_pwr->pwrlevel[i].io_fraction;
 	}
 	/* Do not set_rate for targets in sync with AXI */
 	if (pwr->pwrlevels[0].gpu_freq > 0)
@@ -583,7 +585,8 @@
 
 	mutex_lock(&device->mutex);
 	if (device->state & (KGSL_STATE_ACTIVE | KGSL_STATE_NAP)) {
-		if (device->requested_state != KGSL_STATE_SLEEP)
+		if ((device->requested_state != KGSL_STATE_SLEEP) &&
+			(device->requested_state != KGSL_STATE_SLUMBER))
 			kgsl_pwrscale_idle(device);
 
 		if (kgsl_pwrctrl_sleep(device) != 0) {
@@ -621,7 +624,8 @@
 void kgsl_pre_hwaccess(struct kgsl_device *device)
 {
 	BUG_ON(!mutex_is_locked(&device->mutex));
-	if (device->state & (KGSL_STATE_SLEEP | KGSL_STATE_NAP))
+	if (device->state & (KGSL_STATE_SLEEP | KGSL_STATE_NAP |
+				KGSL_STATE_SLUMBER))
 		kgsl_pwrctrl_wake(device);
 }
 EXPORT_SYMBOL(kgsl_pre_hwaccess);
@@ -633,14 +637,46 @@
 		mutex_unlock(&device->mutex);
 		wait_for_completion(&device->hwaccess_gate);
 		mutex_lock(&device->mutex);
-	}
-	if (device->state == KGSL_STATE_DUMP_AND_RECOVER) {
+	} else if (device->state == KGSL_STATE_DUMP_AND_RECOVER) {
 		mutex_unlock(&device->mutex);
 		wait_for_completion(&device->recovery_gate);
 		mutex_lock(&device->mutex);
-	}
- }
+	} else if (device->state == KGSL_STATE_SLUMBER)
+		kgsl_pwrctrl_wake(device);
+}
 
+static int
+_slumber(struct kgsl_device *device)
+{
+	int status = -EINVAL;
+	if (!device)
+		return -EINVAL;
+	KGSL_PWR_WARN(device, "Slumber start\n");
+
+	device->requested_state = KGSL_STATE_SLUMBER;
+	del_timer(&device->idle_timer);
+	switch (device->state) {
+	case KGSL_STATE_ACTIVE:
+		/* Wait for the device to become idle */
+		device->ftbl->idle(device, KGSL_TIMEOUT_DEFAULT);
+	case KGSL_STATE_NAP:
+	case KGSL_STATE_SLEEP:
+		device->ftbl->suspend_context(device);
+		device->ftbl->stop(device);
+		device->state = KGSL_STATE_SLUMBER;
+		device->pwrctrl.restore_slumber = 1;
+		KGSL_PWR_WARN(device, "state -> SLUMBER, device %d\n",
+				device->id);
+		break;
+	default:
+		break;
+	}
+	status = 0;
+	/* Don't set requested state to NONE
+	It's done in kgsl_pwrctrl_sleep*/
+	KGSL_PWR_WARN(device, "Done going to slumber\n");
+	return status;
+}
 
 /******************************************************************/
 /* Caller must hold the device mutex. */
@@ -650,18 +686,32 @@
 	KGSL_PWR_INFO(device, "sleep device %d\n", device->id);
 
 	/* Work through the legal state transitions */
-	if (device->requested_state == KGSL_STATE_NAP) {
-		if (device->ftbl->isidle(device))
+	if ((device->requested_state == KGSL_STATE_NAP)) {
+		if (device->pwrctrl.restore_slumber) {
+			device->requested_state = KGSL_STATE_NONE;
+			return 0;
+		} else if (device->ftbl->isidle(device))
 			goto nap;
 	} else if (device->requested_state == KGSL_STATE_SLEEP) {
 		if (device->state == KGSL_STATE_NAP ||
-			device->ftbl->isidle(device))
-			goto sleep;
+			device->ftbl->isidle(device)) {
+			if (!device->pwrctrl.restore_slumber)
+				goto sleep;
+			else
+				goto slumber;
+			}
+	} else if (device->requested_state == KGSL_STATE_SLUMBER) {
+		if (device->ftbl->isidle(device))
+			goto slumber;
 	}
 
 	device->requested_state = KGSL_STATE_NONE;
 	return -EBUSY;
 
+
+slumber:
+	_slumber(device);
+
 sleep:
 	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
 	kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_OFF);
@@ -693,6 +743,24 @@
 }
 EXPORT_SYMBOL(kgsl_pwrctrl_sleep);
 
+static int
+_wake_from_slumber(struct kgsl_device *device)
+{
+	int status = -EINVAL;
+	if (!device)
+		return -EINVAL;
+
+	KGSL_PWR_WARN(device, "wake from slumber start\n");
+
+	device->requested_state = KGSL_STATE_ACTIVE;
+	kgsl_pwrctrl_pwrlevel_change(device, KGSL_PWRLEVEL_NOMINAL);
+	status = device->ftbl->start(device, 0);
+	device->requested_state = KGSL_STATE_NONE;
+
+	KGSL_PWR_WARN(device, "Done waking from slumber\n");
+	return status;
+}
+
 /******************************************************************/
 /* Caller must hold the device mutex. */
 void kgsl_pwrctrl_wake(struct kgsl_device *device)
@@ -700,6 +768,9 @@
 	if (device->state == KGSL_STATE_SUSPEND)
 		return;
 
+	if (device->state == KGSL_STATE_SLUMBER)
+		_wake_from_slumber(device);
+
 	if (device->state != KGSL_STATE_NAP) {
 		kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_ON);
 		kgsl_pwrscale_wake(device);
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.h b/drivers/gpu/msm/kgsl_pwrctrl.h
index 127a19b..6258a9b 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.h
+++ b/drivers/gpu/msm/kgsl_pwrctrl.h
@@ -21,7 +21,6 @@
 
 #define KGSL_PWRLEVEL_TURBO 0
 #define KGSL_PWRLEVEL_NOMINAL 1
-#define KGSL_PWRLEVEL_LOW_OFFSET 2
 
 #define KGSL_MAX_CLKS 5
 
@@ -56,6 +55,7 @@
 	const char *src_clk_name;
 	s64 time;
 	struct kgsl_busy busy;
+	unsigned int restore_slumber;
 };
 
 void kgsl_pwrctrl_clk(struct kgsl_device *device, int state);
diff --git a/drivers/hwmon/msm_adc.c b/drivers/hwmon/msm_adc.c
index 42bcd07..b8d581e 100644
--- a/drivers/hwmon/msm_adc.c
+++ b/drivers/hwmon/msm_adc.c
@@ -98,6 +98,8 @@
 /* Needed to support file_op interfaces */
 static struct msm_adc_drv *msm_adc_drv;
 
+static bool conv_first_request;
+
 static ssize_t msm_adc_show_curr(struct device *dev,
 				struct device_attribute *devattr, char *buf);
 
@@ -726,6 +728,16 @@
 	struct msm_adc_platform_data *pdata =
 					msm_adc_drv->pdev->dev.platform_data;
 	struct msm_adc_channels *channel = &pdata->channel[hwmon_chan];
+	int ret = 0;
+
+	if (conv_first_request) {
+		ret = pm8058_xoadc_calib_device(channel->adc_dev_instance);
+		if (ret) {
+			pr_err("pmic8058 xoadc calibration failed, retry\n");
+			return ret;
+		}
+		conv_first_request = false;
+	}
 
 	channel->adc_access_fn->adc_slot_request(channel->adc_dev_instance,
 									&slot);
@@ -813,6 +825,16 @@
 					msm_adc_drv->pdev->dev.platform_data;
 	struct msm_adc_channels *channel = &pdata->channel[client->adc_chan];
 	struct adc_conv_slot *slot;
+	int ret;
+
+	if (conv_first_request) {
+		ret = pm8058_xoadc_calib_device(channel->adc_dev_instance);
+		if (ret) {
+			pr_err("pmic8058 xoadc calibration failed, retry\n");
+			return ret;
+		}
+		conv_first_request = false;
+	}
 
 	channel->adc_access_fn->adc_slot_request(channel->adc_dev_instance,
 									&slot);
@@ -871,46 +893,6 @@
 	return rc;
 }
 
-int32_t adc_calib_request(void *h, struct completion *calib_complete_evt)
-{
-	struct msm_client_data *client = (struct msm_client_data *)h;
-	struct msm_adc_platform_data *pdata =
-					msm_adc_drv->pdev->dev.platform_data;
-	struct msm_adc_channels *channel = &pdata->channel[client->adc_chan];
-	struct adc_conv_slot *slot;
-	int rc, calib_status;
-
-	channel->adc_access_fn->adc_slot_request(channel->adc_dev_instance,
-				&slot);
-	if (slot) {
-		slot->conv.result.chan = client->adc_chan;
-		slot->blocking = 0;
-		slot->compk = calib_complete_evt;
-		slot->adc_request = START_OF_CALIBRATION;
-		slot->chan_path = channel->chan_path_type;
-		slot->chan_adc_config = channel->adc_config_type;
-		slot->chan_adc_calib = channel->adc_calib_type;
-		rc = channel->adc_access_fn->adc_calibrate(
-			channel->adc_dev_instance, slot, &calib_status);
-
-		if (calib_status == CALIB_NOT_REQUIRED) {
-			channel->adc_access_fn->adc_restore_slot(
-					channel->adc_dev_instance, slot);
-			/* client will always wait in case when
-				calibration is not required */
-			complete(calib_complete_evt);
-		} else {
-			atomic_inc(&msm_adc_drv->total_outst);
-			mutex_lock(&client->lock);
-			client->num_outstanding++;
-			mutex_unlock(&client->lock);
-		}
-
-		return rc;
-	}
-	return -EBUSY;
-}
-
 static void msm_rpc_adc_conv_cb(void *context, u32 param,
 			    void *evt_buf, u32 len)
 {
@@ -1458,6 +1440,7 @@
 		else
 			msm_rpc_adc_init(pdev);
 	}
+	conv_first_request = true;
 
 	pr_info("msm_adc successfully registered\n");
 
diff --git a/drivers/input/touchscreen/cyttsp-i2c.c b/drivers/input/touchscreen/cyttsp-i2c.c
index aefce3e..4aa4796 100644
--- a/drivers/input/touchscreen/cyttsp-i2c.c
+++ b/drivers/input/touchscreen/cyttsp-i2c.c
@@ -36,7 +36,6 @@
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/timer.h>
-#include <linux/workqueue.h>
 #include <linux/byteorder/generic.h>
 #include <linux/bitops.h>
 #include <linux/pm_runtime.h>
@@ -61,7 +60,6 @@
 struct cyttsp {
 	struct i2c_client *client;
 	struct input_dev *input;
-	struct work_struct work;
 	struct timer_list timer;
 	struct mutex mutex;
 	char phys[32];
@@ -93,13 +91,10 @@
 static void cyttsp_late_resume(struct early_suspend *handler);
 #endif /* CONFIG_HAS_EARLYSUSPEND */
 
-static struct workqueue_struct *cyttsp_ts_wq;
-
 
 /* ****************************************************************************
  * Prototypes for static functions
  * ************************************************************************** */
-static void cyttsp_xy_worker(struct work_struct *work);
 static irqreturn_t cyttsp_irq(int irq, void *handle);
 static int cyttsp_inlist(u16 prev_track[],
 			u8 cur_trk_id, u8 *prev_loc, u8 num_touches);
@@ -690,11 +685,6 @@
 	else
 		disable_irq(ts->client->irq);
 
-	rc = cancel_work_sync(&ts->work);
-
-	if (rc && ts->client->irq)
-		enable_irq(ts->client->irq);
-
 	/* enter bootloader idle mode */
 	rc = cyttsp_soft_reset(ts);
 
@@ -922,12 +912,8 @@
 static DEVICE_ATTR(cyttsp_fw_name, 0664, cyttsp_fw_name_show,
 					cyttsp_fw_name_store);
 
-/* The cyttsp_xy_worker function reads the XY coordinates and sends them to
- * the input layer.  It is scheduled from the interrupt (or timer).
- */
-void cyttsp_xy_worker(struct work_struct *work)
+static void cyttsp_xy_handler(struct cyttsp *ts)
 {
-	struct cyttsp *ts = container_of(work, struct cyttsp, work);
 	u8 id, tilt, rev_x, rev_y;
 	u8 i, loc;
 	u8 prv_tch;		/* number of previous touches */
@@ -950,7 +936,7 @@
 	u8 st_z2;
 	s32 retval;
 
-	cyttsp_xdebug("TTSP worker start 1:\n");
+	cyttsp_xdebug("TTSP handler start 1:\n");
 
 	/* get event data from CYTTSP device */
 	i = CY_NUM_RETRY;
@@ -963,10 +949,10 @@
 	if (retval < CY_OK) {
 		/* return immediately on
 		 * failure to read device on the i2c bus */
-		goto exit_xy_worker;
+		goto exit_xy_handler;
 	}
 
-	cyttsp_xdebug("TTSP worker start 2:\n");
+	cyttsp_xdebug("TTSP handler start 2:\n");
 
 	/* compare own irq counter with the device irq counter */
 	if (ts->client->irq) {
@@ -1043,7 +1029,7 @@
 				tries++ < 100);
 			cyttsp_putbl(ts, 2, true, false, false);
 		}
-		goto exit_xy_worker;
+		goto exit_xy_handler;
 	} else {
 		cur_tch = GET_NUM_TOUCHES(g_xy_data.tt_stat);
 		if (IS_LARGE_AREA(g_xy_data.tt_stat)) {
@@ -1126,7 +1112,7 @@
 	if ((prv_tch == CY_NTCH) &&
 		((cur_tch == CY_NTCH) ||
 		(cur_tch > CY_NUM_MT_TCH_ID))) {
-		goto exit_xy_worker;
+		goto exit_xy_handler;
 	}
 
 	cyttsp_debug("prev=%d  curr=%d\n", prv_tch, cur_tch);
@@ -1816,19 +1802,10 @@
 		ts->act_trk[id] = cur_trk[id];
 	}
 
-exit_xy_worker:
-	if (cyttsp_disable_touch) {
-		/* Turn off the touch interrupts */
-		cyttsp_debug("Not enabling touch\n");
-	} else {
-		if (ts->client->irq == 0) {
-			/* restart event timer */
-			mod_timer(&ts->timer, jiffies + TOUCHSCREEN_TIMEOUT);
-		} else {
-			/* re-enable the interrupt after processing */
-			enable_irq(ts->client->irq);
-		}
-	}
+exit_xy_handler:
+	/* restart event timer */
+	if (ts->client->irq == 0)
+		mod_timer(&ts->timer, jiffies + TOUCHSCREEN_TIMEOUT);
 	return;
 }
 
@@ -1882,7 +1859,7 @@
 	cyttsp_xdebug("TTSP Device timer event\n");
 
 	/* schedule motion signal handling */
-	queue_work(cyttsp_ts_wq, &ts->work);
+	cyttsp_xy_handler(ts);
 
 	return;
 }
@@ -1899,11 +1876,8 @@
 
 	cyttsp_xdebug("%s: Got IRQ\n", CY_I2C_NAME);
 
-	/* disable further interrupts until this interrupt is processed */
-	disable_irq_nosync(ts->client->irq);
+	cyttsp_xy_handler(ts);
 
-	/* schedule motion signal handling */
-	queue_work(cyttsp_ts_wq, &ts->work);
 	return IRQ_HANDLED;
 }
 
@@ -2565,9 +2539,6 @@
 		goto error_free_device;
 	}
 
-	/* Prepare our worker structure prior to setting up the timer/ISR */
-	INIT_WORK(&ts->work, cyttsp_xy_worker);
-
 	if (gpio_is_valid(ts->platform_data->resout_gpio)) {
 		/* configure touchscreen reset out gpio */
 		retval = gpio_request(ts->platform_data->resout_gpio,
@@ -2664,9 +2635,8 @@
 		mod_timer(&ts->timer, jiffies + TOUCHSCREEN_TIMEOUT);
 	} else {
 		cyttsp_info("Setting up interrupt\n");
-		/* request_irq() will also call enable_irq() */
-		error = request_irq(client->irq, cyttsp_irq,
-			IRQF_TRIGGER_FALLING,
+		error = request_threaded_irq(client->irq, NULL, cyttsp_irq,
+			IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 			client->dev.driver->name, ts);
 		if (error) {
 			cyttsp_alert("error: could not request irq\n");
@@ -2988,15 +2958,10 @@
 		return 0;
 	}
 
-	/* disable worker */
 	if (ts->client->irq == 0)
 		del_timer(&ts->timer);
 	else
-		disable_irq_nosync(ts->client->irq);
-	retval = cancel_work_sync(&ts->work);
-
-	if (retval)
-		enable_irq(ts->client->irq);
+		disable_irq(ts->client->irq);
 
 	if (!(retval < CY_OK)) {
 		if (ts->platform_data->use_sleep &&
@@ -3058,10 +3023,6 @@
 	device_remove_file(&client->dev, &dev_attr_cyttsp_force_update_fw);
 	device_remove_file(&client->dev, &dev_attr_cyttsp_fw_name);
 
-	/* Start cleaning up by removing any delayed work and the timer */
-	if (cancel_delayed_work((struct delayed_work *)&ts->work) < CY_OK)
-		cyttsp_alert("error: could not remove work from workqueue\n");
-
 	/* free up timer or irq */
 	if (ts->client->irq == 0) {
 		err = del_timer(&ts->timer);
@@ -3127,12 +3088,6 @@
 	cyttsp_info("I2C Touchscreen Driver (Built %s @ %s)\n", \
 		__DATE__, __TIME__);
 
-	cyttsp_ts_wq = create_singlethread_workqueue("cyttsp_ts_wq");
-	if (cyttsp_ts_wq == NULL) {
-		cyttsp_debug("No memory for cyttsp_ts_wq\n");
-		return -ENOMEM;
-	}
-
 	ret = i2c_add_driver(&cyttsp_driver);
 
 	return ret;
@@ -3140,8 +3095,6 @@
 
 static void cyttsp_exit(void)
 {
-	if (cyttsp_ts_wq)
-		destroy_workqueue(cyttsp_ts_wq);
 	return i2c_del_driver(&cyttsp_driver);
 }
 
diff --git a/drivers/media/radio/radio-iris-transport.c b/drivers/media/radio/radio-iris-transport.c
index 6628c9d..50ca58c 100644
--- a/drivers/media/radio/radio-iris-transport.c
+++ b/drivers/media/radio/radio-iris-transport.c
@@ -51,13 +51,13 @@
 	len = smd_read_avail(hsmd->fm_channel);
 
 	while (len) {
-		skb = alloc_skb(len, GFP_KERNEL);
+		skb = alloc_skb(len, GFP_ATOMIC);
 		if (!skb) {
 			FMDERR("Memory not allocated for the socket");
 			return;
 		}
 
-		buf = kmalloc(len, GFP_KERNEL);
+		buf = kmalloc(len, GFP_ATOMIC);
 		if (!buf) {
 			kfree_skb(skb);
 			FMDERR("Error in allocating buffer memory");
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index a256e51..2d42e17 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -1661,7 +1661,7 @@
 	memcpy(data, &skb->data[PEEK_DATA_OFSET], len);
 	iris_q_evt_data(radio, data, len, IRIS_BUF_PEEK);
 	radio_hci_req_complete(hdev, status);
-
+	kfree(data);
 
 }
 
@@ -1872,9 +1872,13 @@
 	int len;
 
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
+	struct hci_fm_station_rsp *rsp;
 
 	len = sizeof(struct hci_fm_station_rsp);
-	memcpy(&radio->fm_st_rsp.station_rsp, skb_pull(skb, len), len);
+	rsp = (struct hci_fm_station_rsp *)skb_pull(skb, len);
+	if (rsp == NULL)
+		return;
+	memcpy(&radio->fm_st_rsp.station_rsp, rsp, len);
 
 	iris_q_event(radio, IRIS_EVT_TUNE_SUCC);
 
@@ -1927,7 +1931,8 @@
 	len = ev->num_stations_found * PARAMS_PER_STATION + STN_FREQ_OFFSET;
 
 	for (cnt = STN_FREQ_OFFSET, stn_num = 0;
-		(cnt < len) && (stn_num < ev->num_stations_found);
+		(cnt < len) && (stn_num < ev->num_stations_found)
+		&& (stn_num < ARRAY_SIZE(ev->rel_freq));
 		cnt += PARAMS_PER_STATION, stn_num++) {
 		abs_freq = *((int *)&skb->data[cnt]);
 		rel_freq = abs_freq - radio->recv_conf.band_low_limit;
@@ -2069,8 +2074,16 @@
 
 void radio_hci_event_packet(struct radio_hci_dev *hdev, struct sk_buff *skb)
 {
-	struct radio_hci_event_hdr *hdr = (void *) skb->data;
-	__u8 event = hdr->evt;
+	struct radio_hci_event_hdr *hdr;
+	u8 event;
+
+	if (skb == NULL) {
+		FMDERR("Socket buffer is NULL");
+		return;
+	}
+
+	hdr = (void *) skb->data;
+	event = hdr->evt;
 
 	skb_pull(skb, RADIO_HCI_EVENT_HDR_SIZE);
 
diff --git a/drivers/media/video/msm/Makefile b/drivers/media/video/msm/Makefile
index 3f41d43..59c4cab 100644
--- a/drivers/media/video/msm/Makefile
+++ b/drivers/media/video/msm/Makefile
@@ -44,3 +44,4 @@
 obj-$(CONFIG_MT9D112) += mt9d112.o mt9d112_reg.o
 
 obj-$(CONFIG_MT9D113) += mt9d113.o mt9d113_reg.o
+obj-$(CONFIG_FB_MSM_WRITEBACK_MSM_PANEL) += wfd/
diff --git a/drivers/media/video/msm/io/Makefile b/drivers/media/video/msm/io/Makefile
index dc8708c..584738d 100644
--- a/drivers/media/video/msm/io/Makefile
+++ b/drivers/media/video/msm/io/Makefile
@@ -1,2 +1,3 @@
 GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
 obj-$(CONFIG_MSM_CAMERA) += msm_camera_i2c.o msm_camera_eeprom.o
+obj-$(CONFIG_MSM_CAMERA) += msm_io_util.o
diff --git a/drivers/media/video/msm/io/msm_io_util.c b/drivers/media/video/msm/io/msm_io_util.c
new file mode 100644
index 0000000..9f58d6e
--- /dev/null
+++ b/drivers/media/video/msm/io/msm_io_util.c
@@ -0,0 +1,68 @@
+/* Copyright (c) 2011, 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
+ * 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/delay.h>
+#include <linux/clk.h>
+#include <mach/board.h>
+#include <mach/camera.h>
+
+int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info,
+		struct clk **clk_ptr, int num_clk, int enable)
+{
+	int i;
+	int rc = 0;
+	if (enable) {
+		for (i = 0; i < num_clk; i++) {
+			clk_ptr[i] = clk_get(dev, clk_info[i].clk_name);
+			if (IS_ERR(clk_ptr[i])) {
+				pr_err("%s get failed\n", clk_info[i].clk_name);
+				rc = PTR_ERR(clk_ptr[i]);
+				goto cam_clk_get_err;
+			}
+			if (clk_info[i].clk_rate >= 0) {
+				rc = clk_set_rate(clk_ptr[i],
+							clk_info[i].clk_rate);
+				if (rc < 0) {
+					pr_err("%s set failed\n",
+						   clk_info[i].clk_name);
+					goto cam_clk_set_err;
+				}
+			}
+			rc = clk_enable(clk_ptr[i]);
+			if (rc < 0) {
+				pr_err("%s enable failed\n",
+					   clk_info[i].clk_name);
+				goto cam_clk_set_err;
+			}
+		}
+	} else {
+		for (i = num_clk - 1; i >= 0; i--) {
+			if (clk_ptr[i] != NULL)
+				clk_disable(clk_ptr[i]);
+				clk_put(clk_ptr[i]);
+		}
+	}
+	return rc;
+
+
+cam_clk_set_err:
+	clk_put(clk_ptr[i]);
+cam_clk_get_err:
+	for (i--; i >= 0; i--) {
+		if (clk_ptr[i] != NULL) {
+			clk_disable(clk_ptr[i]);
+			clk_put(clk_ptr[i]);
+		}
+	}
+	return rc;
+}
+
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index 40a273a..4b4d235 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -1427,7 +1427,9 @@
 			mutex_unlock(&pcam->vid_lock);
 			return rc;
 		}
-
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+		pcam->mctl.client = msm_ion_client_create(-1, "camera");
+#endif
 		/* Should be set to sensor ops if any but right now its OK!! */
 		if (!pcam->mctl.mctl_open) {
 			D("%s: media contoller is not inited\n",
@@ -1603,7 +1605,9 @@
 			if (rc < 0)
 				pr_err("mctl_release fails %d\n", rc);
 		}
-
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+		ion_client_destroy(pcam->mctl.client);
+#endif
 		dma_release_declared_memory(&pcam->pdev->dev);
 	}
 	mutex_unlock(&pcam->vid_lock);
@@ -1903,13 +1907,13 @@
 	case MSM_CAM_IOCTL_REGISTER_PMEM:
 		return msm_register_pmem(
 			&config_cam->p_mctl->sync.pmem_stats,
-			(void __user *)arg);
+			(void __user *)arg, config_cam->p_mctl->client);
 		break;
 
 	case MSM_CAM_IOCTL_UNREGISTER_PMEM:
 		return msm_pmem_table_del(
 			&config_cam->p_mctl->sync.pmem_stats,
-			(void __user *)arg);
+			(void __user *)arg, config_cam->p_mctl->client);
 		break;
 	case VIDIOC_SUBSCRIBE_EVENT:
 		if (copy_from_user(&temp_sub,
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index 083fc57..f9cf5de 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -31,6 +31,7 @@
 #include <media/msm_isp.h>
 #include <mach/camera.h>
 #include <media/msm_isp.h>
+#include <linux/ion.h>
 
 #define MSM_V4L2_DIMENSION_SIZE 96
 #define MAX_DEV_NAME_LEN 50
@@ -219,6 +220,7 @@
 
 	struct pm_qos_request_list pm_qos_req_list;
 	struct msm_mctl_pp_info pp_info;
+	struct ion_client *client;
 };
 
 /* abstract camera device represents a VFE and connected sensor */
@@ -402,8 +404,10 @@
 int msm_mctl_release_free_buf(struct msm_cam_media_controller *pmctl,
 				int path, struct msm_free_buf *free_buf);
 /*Memory(PMEM) functions*/
-int msm_register_pmem(struct hlist_head *ptype, void __user *arg);
-int msm_pmem_table_del(struct hlist_head *ptype, void __user *arg);
+int msm_register_pmem(struct hlist_head *ptype, void __user *arg,
+				struct ion_client *client);
+int msm_pmem_table_del(struct hlist_head *ptype, void __user *arg,
+				struct ion_client *client);
 int msm_pmem_region_get_phy_addr(struct hlist_head *ptype,
 	struct msm_mem_map_info *mem_map, int32_t *phyaddr);
 uint8_t msm_pmem_region_lookup(struct hlist_head *ptype,
diff --git a/drivers/media/video/msm/msm_mctl_buf.c b/drivers/media/video/msm/msm_mctl_buf.c
index 1bbb029..f7e5479 100644
--- a/drivers/media/video/msm/msm_mctl_buf.c
+++ b/drivers/media/video/msm/msm_mctl_buf.c
@@ -115,7 +115,7 @@
 			rc = videobuf2_pmem_contig_user_get(mem, &offset,
 				buf_type,
 				pcam_inst->buf_offset[buf_idx][i].addr_offset,
-				pcam_inst->path);
+				pcam_inst->path, pcam->mctl.client);
 		else
 			rc = videobuf2_pmem_contig_mmap_get(mem, &offset,
 				buf_type, pcam_inst->path);
@@ -241,7 +241,7 @@
 	}
 	for (i = 0; i < vb->num_planes; i++) {
 		mem = vb2_plane_cookie(vb, i);
-		videobuf2_pmem_contig_user_put(mem);
+		videobuf2_pmem_contig_user_put(mem, pcam->mctl.client);
 	}
 	buf->state = MSM_BUFFER_STATE_UNUSED;
 }
diff --git a/drivers/media/video/msm/msm_mem.c b/drivers/media/video/msm/msm_mem.c
index 5c64e01..b6dbe87 100644
--- a/drivers/media/video/msm/msm_mem.c
+++ b/drivers/media/video/msm/msm_mem.c
@@ -124,49 +124,57 @@
 }
 
 static int msm_pmem_table_add(struct hlist_head *ptype,
-	struct msm_pmem_info *info)
+	struct msm_pmem_info *info, struct ion_client *client)
 {
-	struct file *file;
 	unsigned long paddr;
 	unsigned int flags;
-#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 	unsigned long kvstart;
-	int rc;
+	struct file *file;
 #endif
+	int rc = -ENOMEM;
+
 	unsigned long len;
 	struct msm_pmem_region *region;
-#ifdef CONFIG_ANDROID_PMEM
+
+	region = kmalloc(sizeof(struct msm_pmem_region), GFP_KERNEL);
+	if (!region)
+		goto out;
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	region->handle = ion_import_fd(client, info->fd);
+	if (IS_ERR_OR_NULL(region->handle))
+		goto OUT1;
+	ion_phys(client, region->handle, &paddr, (size_t *)&len);
+#elif CONFIG_ANDROID_PMEM
 	rc = get_pmem_file(info->fd, &paddr, &kvstart, &len, &file);
 	if (rc < 0) {
 		pr_err("%s: get_pmem_file fd %d error %d\n",
-						__func__,
-						info->fd, rc);
-		return rc;
+				__func__, info->fd, rc);
+		goto out1;
 	}
-	if (!info->len)
-		info->len = len;
-
-	rc = check_pmem_info(info, len);
-	if (rc < 0)
-		return rc;
+	region->file = file;
 #else
 	paddr = 0;
 	file = NULL;
+	kvstart = 0;
 #endif
+	if (!info->len)
+		info->len = len;
+	rc = check_pmem_info(info, len);
+	if (rc < 0)
+		goto out2;
 	paddr += info->offset;
 	len = info->len;
 
-	if (check_overlap(ptype, paddr, len) < 0)
-		return -EINVAL;
+	if (check_overlap(ptype, paddr, len) < 0) {
+		rc = -EINVAL;
+		goto out2;
+	}
 
 	CDBG("%s: type %d, active flag %d, paddr 0x%lx, vaddr 0x%lx\n",
 		__func__, info->type, info->active, paddr,
 		(unsigned long)info->vaddr);
 
-	region = kmalloc(sizeof(struct msm_pmem_region), GFP_KERNEL);
-	if (!region)
-		return -ENOMEM;
-
 	INIT_HLIST_NODE(&region->list);
 	flags = MSM_SUBSYSTEM_MAP_IOVA;
 	region->subsys_id = MSM_SUBSYSTEM_CAMERA;
@@ -174,13 +182,12 @@
 					flags, &(region->subsys_id), 1);
 	if (IS_ERR((void *)region->msm_buffer)) {
 		pr_err("%s: msm_subsystem_map_buffer failed\n", __func__);
-		kfree(region);
-		put_pmem_file(file);
-		return PTR_ERR((void *)region->msm_buffer);
+		rc = PTR_ERR((void *)region->msm_buffer);
+		goto out2;
 	}
-	region->paddr = region->msm_buffer->iova[0];
+	paddr = region->msm_buffer->iova[0];
+	region->paddr = paddr;
 	region->len = len;
-	region->file = file;
 	memcpy(&region->info, info, sizeof(region->info));
 	D("%s Adding region to list with type %d\n", __func__,
 						region->info.type);
@@ -188,10 +195,20 @@
 	hlist_add_head(&(region->list), ptype);
 
 	return 0;
+out2:
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	ion_free(client, region->handle);
+#elif CONFIG_ANDROID_PMEM
+	put_pmem_file(region->file);
+#endif
+out1:
+	kfree(region);
+out:
+	return rc;
 }
 
 static int __msm_register_pmem(struct hlist_head *ptype,
-			struct msm_pmem_info *pinfo)
+			struct msm_pmem_info *pinfo, struct ion_client *client)
 {
 	int rc = 0;
 
@@ -203,7 +220,7 @@
 	case MSM_PMEM_CS:
 	case MSM_PMEM_IHIST:
 	case MSM_PMEM_SKIN:
-		rc = msm_pmem_table_add(ptype, pinfo);
+		rc = msm_pmem_table_add(ptype, pinfo, client);
 		break;
 
 	default:
@@ -215,7 +232,7 @@
 }
 
 static int __msm_pmem_table_del(struct hlist_head *ptype,
-			struct msm_pmem_info *pinfo)
+			struct msm_pmem_info *pinfo, struct ion_client *client)
 {
 	int rc = 0;
 	struct msm_pmem_region *region;
@@ -235,16 +252,16 @@
 			if (pinfo->type == region->info.type &&
 				pinfo->vaddr == region->info.vaddr &&
 				pinfo->fd == region->info.fd) {
+				hlist_del(node);
 				if (msm_subsystem_unmap_buffer
 					(region->msm_buffer) < 0)
 					pr_err(
 					"%s: unmapped stat memory\n",
-					__func__);
-				hlist_del(node);
-#ifdef CONFIG_ANDROID_PMEM
-				put_pmem_file(region->file);
+				__func__);
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+				ion_free(client, region->handle);
 #else
-
+				put_pmem_file(region->file);
 #endif
 				kfree(region);
 			}
@@ -381,7 +398,8 @@
 	return 0;
 }
 
-int msm_register_pmem(struct hlist_head *ptype, void __user *arg)
+int msm_register_pmem(struct hlist_head *ptype, void __user *arg,
+					  struct ion_client *client)
 {
 	struct msm_pmem_info info;
 
@@ -390,11 +408,12 @@
 			return -EFAULT;
 	}
 
-	return __msm_register_pmem(ptype, &info);
+	return __msm_register_pmem(ptype, &info, client);
 }
 EXPORT_SYMBOL(msm_register_pmem);
 
-int msm_pmem_table_del(struct hlist_head *ptype, void __user *arg)
+int msm_pmem_table_del(struct hlist_head *ptype, void __user *arg,
+					   struct ion_client *client)
 {
 	struct msm_pmem_info info;
 
@@ -403,6 +422,6 @@
 		return -EFAULT;
 	}
 
-	return __msm_pmem_table_del(ptype, &info);
+	return __msm_pmem_table_del(ptype, &info, client);
 }
 EXPORT_SYMBOL(msm_pmem_table_del);
diff --git a/drivers/media/video/msm/msm_vfe32.c b/drivers/media/video/msm/msm_vfe32.c
index 5c02f85..4a3e49f 100644
--- a/drivers/media/video/msm/msm_vfe32.c
+++ b/drivers/media/video/msm/msm_vfe32.c
@@ -210,6 +210,15 @@
 			V32_CLF_LUMA_UPDATE_OFF},
 		{VFE_CMD_CLF_CHROMA_UPDATE, V32_CLF_CHROMA_UPDATE_LEN,
 			V32_CLF_CHROMA_UPDATE_OFF},
+/*120*/ {VFE_CMD_PCA_ROLL_OFF_CFG},
+		{VFE_CMD_PCA_ROLL_OFF_UPDATE},
+		{VFE_CMD_GET_REG_DUMP},
+		{VFE_CMD_GET_LINEARIZATON_TABLE},
+		{VFE_CMD_GET_MESH_ROLLOFF_TABLE},
+/*125*/ {VFE_CMD_GET_PCA_ROLLOFF_TABLE},
+		{VFE_CMD_GET_RGB_G_TABLE},
+		{VFE_CMD_GET_LA_TABLE},
+		{VFE_CMD_DEMOSAICV3_UPDATE},
 };
 
 uint32_t vfe32_AXI_WM_CFG[] = {
@@ -343,6 +352,15 @@
 	"CLF_CFG",
 	"CLF_LUMA_UPDATE",
 	"CLF_CHROMA_UPDATE",
+	"PCA_ROLL_OFF_CFG", /*120*/
+	"PCA_ROLL_OFF_UPDATE",
+	"GET_REG_DUMP",
+	"GET_LINEARIZATON_TABLE",
+	"GET_MESH_ROLLOFF_TABLE",
+	"GET_PCA_ROLLOFF_TABLE", /*125*/
+	"GET_RGB_G_TABLE",
+	"GET_LA_TABLE",
+	"DEMOSAICV3_UPDATE",
 };
 
 static void vfe32_stop(void)
@@ -1020,6 +1038,7 @@
 	/* set bit 8 for auto increment. */
 	uint32_t value = VFE_DMI_CFG_DEFAULT;
 	value += (uint32_t)bankSel;
+	CDBG("%s: banksel = %d\n", __func__, bankSel);
 
 	msm_io_w(value, vfe32_ctrl->vfebase + VFE_DMI_CFG);
 	/* by default, always starts with offset 0.*/
@@ -2146,9 +2165,9 @@
 
 		CDBG("%s: start writing RollOff Ram0 table\n", __func__);
 		if (temp2)
-			vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK1);
-		else
 			vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK0);
+		else
+			vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK1);
 
 		msm_io_w(temp1, vfe32_ctrl->vfebase + VFE_DMI_ADDR);
 		for (i = 0 ; i < V33_PCA_ROLL_OFF_TABLE_SIZE ; i++) {
@@ -2162,9 +2181,9 @@
 
 		CDBG("%s: start writing RollOff Ram1 table\n", __func__);
 		if (temp2)
-			vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK1);
-		else
 			vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK0);
+		else
+			vfe32_program_dmi_cfg(ROLLOFF_RAM1_BANK1);
 
 		msm_io_w(temp1, vfe32_ctrl->vfebase + VFE_DMI_ADDR);
 		for (i = 0 ; i < V33_PCA_ROLL_OFF_TABLE_SIZE ; i++) {
diff --git a/drivers/media/video/msm/wfd/Makefile b/drivers/media/video/msm/wfd/Makefile
new file mode 100644
index 0000000..e1484aa
--- /dev/null
+++ b/drivers/media/video/msm/wfd/Makefile
@@ -0,0 +1,4 @@
+#obj-$(CONFIG_MSM_WFD_V4L2) += wfd-ioctl.o
+#obj-$(CONFIG_MSM_WFD_V4L2) += enc-subdev.o
+obj-y += mdp-subdev.o
+obj-y += wfd-ioctl.o
diff --git a/drivers/media/video/msm/wfd/mdp-subdev.c b/drivers/media/video/msm/wfd/mdp-subdev.c
new file mode 100644
index 0000000..ed72ca8
--- /dev/null
+++ b/drivers/media/video/msm/wfd/mdp-subdev.c
@@ -0,0 +1,275 @@
+/* Copyright (c) 2011, 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
+* 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 "mdp-subdev.h"
+#include "wfd-util.h"
+#include <media/videobuf2-core.h>
+#include <linux/msm_mdp.h>
+
+struct mdp_instance {
+	struct fb_info *mdp;
+	u32 height;
+	u32 width;
+};
+
+int mdp_init(struct v4l2_subdev *sd, u32 val)
+{
+	return 0;
+}
+int mdp_open(struct v4l2_subdev *sd, void *arg)
+{
+	struct mdp_instance *inst = kzalloc(sizeof(struct mdp_instance),
+					GFP_KERNEL);
+	void **cookie = (void **)arg;
+	int rc = 0;
+	struct fb_info *fbi = NULL;
+
+	if (!inst) {
+		WFD_MSG_ERR("Out of memory\n");
+		return -ENOMEM;
+	}
+
+	fbi = msm_fb_get_writeback_fb();
+	if (!fbi) {
+		WFD_MSG_ERR("Failed to acquire mdp instance\n");
+		rc = -ENODEV;
+		goto exit;
+	}
+
+	/*Tell HDMI daemon to open fb1*/
+	rc = kobject_uevent(&fbi->dev->kobj, KOBJ_ADD);
+	if (rc) {
+		WFD_MSG_ERR("Failed add to kobj");
+		goto exit;
+	}
+
+	msm_fb_writeback_init(fbi);
+	inst->mdp = fbi;
+	*cookie = inst;
+	return rc;
+exit:
+	kfree(inst);
+	return rc;
+}
+
+int mdp_start(struct v4l2_subdev *sd, void *arg)
+{
+	struct mdp_instance *inst = arg;
+	int rc = 0;
+	struct fb_info *fbi = NULL;
+	if (inst) {
+		fbi = msm_fb_get_writeback_fb();
+		if (!fbi) {
+			WFD_MSG_ERR("Failed to acquire mdp instance\n");
+			rc = -ENODEV;
+			goto exit;
+		}
+		rc = kobject_uevent(&fbi->dev->kobj, KOBJ_ONLINE);
+		if (rc)
+			WFD_MSG_ERR("Failed to send ONLINE event\n");
+	}
+exit:
+	return rc;
+}
+int mdp_stop(struct v4l2_subdev *sd, void *arg)
+{
+	struct mdp_instance *inst = arg;
+	int rc = 0;
+	struct fb_info *fbi = NULL;
+	if (inst) {
+		fbi = (struct fb_info *)inst->mdp;
+		rc = kobject_uevent(&fbi->dev->kobj, KOBJ_OFFLINE);
+		if (rc) {
+			WFD_MSG_ERR("Failed to send offline event\n");
+			return -EIO;
+		}
+	}
+	return 0;
+}
+int mdp_close(struct v4l2_subdev *sd, void *arg)
+{
+	struct mdp_instance *inst = arg;
+	struct fb_info *fbi = NULL;
+	if (inst) {
+		fbi = (struct fb_info *)inst->mdp;
+		msm_fb_writeback_terminate(fbi);
+		kfree(inst);
+	}
+	return 0;
+}
+int mdp_q_buffer(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct mdp_buf_info *binfo = arg;
+	struct msmfb_data fbdata;
+	struct mdp_instance *inst;
+	if (!binfo || !binfo->inst || !binfo->b) {
+		WFD_MSG_ERR("Invalid argument\n");
+		return -EINVAL;
+	}
+	inst = binfo->inst;
+	fbdata.offset = binfo->offset;
+	fbdata.memory_id = binfo->fd;
+	fbdata.id = 0;
+	fbdata.flags = 0;
+	fbdata.priv = (uint32_t)binfo->b;
+
+	WFD_MSG_INFO("queue buffer to mdp with offset = %u,"
+			"fd = %u, priv = %u\n",
+			fbdata.offset, fbdata.memory_id, fbdata.priv);
+	rc = msm_fb_writeback_queue_buffer(inst->mdp, &fbdata);
+
+	if (rc)
+		WFD_MSG_ERR("Failed to queue buffer\n");
+	return rc;
+}
+int mdp_dq_buffer(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct mdp_buf_info *obuf = arg;
+	struct msmfb_data fbdata;
+	struct mdp_instance *inst;
+	if (!arg) {
+		WFD_MSG_ERR("Invalid argument\n");
+		return -EINVAL;
+	}
+
+	inst = obuf->inst;
+	fbdata.flags = MSMFB_WRITEBACK_DEQUEUE_BLOCKING;
+	rc = msm_fb_writeback_dequeue_buffer(inst->mdp, &fbdata);
+	if (rc) {
+		WFD_MSG_ERR("Failed to dequeue buffer\n");
+		return rc;
+	}
+	WFD_MSG_INFO("dequeue buffer from mdp with offset = %u,"
+			"fd = %u, priv = %u\n",
+			fbdata.offset, fbdata.memory_id, fbdata.priv);
+	obuf->b = (struct vb2_buffer *)fbdata.priv;
+	return rc;
+}
+int mdp_prepare_buffer(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct mdp_buf_info *binfo = arg;
+	struct msmfb_writeback_data wbdata;
+	struct mdp_instance *inst;
+
+	if (!binfo || !binfo->inst || !binfo->b) {
+		WFD_MSG_ERR("Invalid argument\n");
+		return -EINVAL;
+	}
+
+	inst = binfo->inst;
+	wbdata.buf_info.offset = binfo->offset;
+	wbdata.buf_info.memory_id = binfo->fd;
+	wbdata.buf_info.id = 0;
+	wbdata.buf_info.flags = 0;
+	wbdata.buf_info.priv = (uint32_t)binfo->b;
+
+	wbdata.img.width = inst->width;
+	wbdata.img.height = inst->height;
+	wbdata.img.format = MDP_RGB_565;
+	WFD_MSG_DBG("offset = %u, fd = %u, width = %u, height = %u,"
+			"uaddr = %u\n", wbdata.buf_info.offset,
+			wbdata.buf_info.memory_id,
+			wbdata.img.width, wbdata.img.height,
+			wbdata.buf_info.priv);
+
+	rc = msm_fb_writeback_register_buffer(inst->mdp, &wbdata);
+	if (rc) {
+		WFD_MSG_ERR("Failed to register buffer\n");
+		return -EIO;
+	}
+	return rc;
+}
+int mdp_set_prop(struct v4l2_subdev *sd, void *arg)
+{
+	struct mdp_prop *prop = (struct mdp_prop *)arg;
+	struct mdp_instance *inst = prop->inst;
+	if (!prop || !inst) {
+		WFD_MSG_ERR("Invalid arguments\n");
+		return -EINVAL;
+	}
+	inst->height = prop->height;
+	inst->width = prop->width;
+	return 0;
+}
+int mdp_release_buffer(struct v4l2_subdev *sd, void *arg)
+{
+	int rc = 0;
+	struct mdp_buf_info *binfo = arg;
+	struct msmfb_writeback_data wbdata;
+	struct mdp_instance *inst;
+	if (!binfo || !binfo->inst || !binfo->b) {
+		WFD_MSG_ERR("Invalid argument\n");
+		return -EINVAL;
+	}
+	inst = binfo->inst;
+
+	wbdata.buf_info.offset = binfo->offset;
+	wbdata.buf_info.memory_id = binfo->fd;
+	wbdata.buf_info.id = 0;
+	wbdata.buf_info.flags = 0;
+	wbdata.buf_info.priv = (uint32_t)binfo->b;
+
+	wbdata.img.width = inst->width;
+	wbdata.img.height = inst->height;
+	wbdata.img.format = MDP_RGB_565;
+
+	rc = msm_fb_writeback_unregister_buffer(inst->mdp, &wbdata);
+
+	if (rc)
+		WFD_MSG_ERR("Failed to unregister buffer\n");
+	return rc;
+}
+long mdp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+	int rc = 0;
+	if (!sd) {
+		WFD_MSG_ERR("Invalid arguments\n");
+		return -EINVAL;
+	}
+	switch (cmd) {
+	case MDP_Q_BUFFER:
+		rc = mdp_q_buffer(sd, arg);
+		break;
+	case MDP_DQ_BUFFER:
+		rc = mdp_dq_buffer(sd, arg);
+		break;
+	case MDP_PREPARE_BUF:
+		rc = mdp_prepare_buffer(sd, arg);
+		break;
+	case MDP_OPEN:
+		rc = mdp_open(sd, arg);
+		break;
+	case MDP_START:
+		rc = mdp_start(sd, arg);
+		break;
+	case MDP_STOP:
+		rc = mdp_stop(sd, arg);
+		break;
+	case MDP_SET_PROP:
+		rc = mdp_set_prop(sd, arg);
+		break;
+	case MDP_RELEASE_BUF:
+		rc = mdp_release_buffer(sd, arg);
+		break;
+	case MDP_CLOSE:
+		rc = mdp_close(sd, arg);
+		break;
+	default:
+		WFD_MSG_ERR("IOCTL: %u not supported\n", cmd);
+		rc = -EINVAL;
+		break;
+	}
+	return rc;
+}
diff --git a/drivers/media/video/msm/wfd/mdp-subdev.h b/drivers/media/video/msm/wfd/mdp-subdev.h
new file mode 100644
index 0000000..fe8963a
--- /dev/null
+++ b/drivers/media/video/msm/wfd/mdp-subdev.h
@@ -0,0 +1,41 @@
+/* Copyright (c) 2011, 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
+* 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/videodev2.h>
+#include <media/v4l2-subdev.h>
+
+#define MDP_MAGIC_IOCTL 'M'
+
+struct mdp_buf_info {
+	void *inst;
+	struct vb2_buffer *b;
+	u32 fd;
+	u32 offset;
+};
+
+struct mdp_prop {
+	void *inst;
+	u32 height;
+	u32 width;
+};
+#define MDP_Q_BUFFER  _IOW(MDP_MAGIC_IOCTL, 1, struct mdp_buf_info *)
+#define MDP_DQ_BUFFER  _IOR(MDP_MAGIC_IOCTL, 2, struct mdp_out_buf *)
+#define MDP_PREPARE_BUF  _IOW(MDP_MAGIC_IOCTL, 3, struct  mdp_buf_info *)
+#define MDP_OPEN  _IOR(MDP_MAGIC_IOCTL, 4, void **)
+#define MDP_SET_PROP  _IOW(MDP_MAGIC_IOCTL, 5, struct mdp_prop *)
+#define MDP_RELEASE_BUF  _IOW(MDP_MAGIC_IOCTL, 6, struct mdp_buf_info *)
+#define MDP_CLOSE  _IOR(MDP_MAGIC_IOCTL, 7, void *)
+#define MDP_START  _IOR(MDP_MAGIC_IOCTL, 8, void *)
+#define MDP_STOP  _IOR(MDP_MAGIC_IOCTL, 9, void *)
+extern int mdp_init(struct v4l2_subdev *sd, u32 val);
+extern long mdp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg);
diff --git a/drivers/media/video/msm/wfd/wfd-ioctl.c b/drivers/media/video/msm/wfd/wfd-ioctl.c
new file mode 100644
index 0000000..9db5b54
--- /dev/null
+++ b/drivers/media/video/msm/wfd/wfd-ioctl.c
@@ -0,0 +1,655 @@
+/* Copyright (c) 2011, 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
+ * 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/types.h>
+#include <linux/list.h>
+#include <linux/ioctl.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/version.h>
+#include <linux/platform_device.h>
+#include <linux/android_pmem.h>
+#include <linux/sched.h>
+#include <linux/kthread.h>
+
+#include <media/v4l2-dev.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-msm-mem.h>
+#include "wfd-util.h"
+#include "mdp-subdev.h"
+
+#define WFD_VERSION KERNEL_VERSION(0, 0, 1)
+#define DEFAULT_WFD_WIDTH 640
+#define DEFAULT_WFD_HEIGHT 480
+#define MIN_BUF_COUNT 2
+
+struct wfd_device {
+	struct platform_device *pdev;
+	struct v4l2_device v4l2_dev;
+	struct video_device *pvdev;
+	struct v4l2_subdev mdp_sdev;
+};
+
+struct mem_info {
+	u32 fd;
+	u32 offset;
+};
+
+struct wfd_inst {
+	struct vb2_queue vid_bufq;
+	spinlock_t buflock;
+	spinlock_t inst_lock;
+	u32 buf_count;
+	struct task_struct *mdp_task;
+	void *mdp_inst;
+	u32 height;
+	u32 width;
+	u32 pixelformat;
+	struct mem_info **minfo;
+	bool streamoff;
+};
+
+struct wfd_vid_buffer {
+	struct vb2_buffer    vidbuf;
+};
+
+static int wfd_vidbuf_queue_setup(struct vb2_queue *q,
+		unsigned int *num_buffers, unsigned int *num_planes,
+		unsigned long sizes[], void *alloc_ctxs[])
+{
+	WFD_MSG_DBG("In %s\n", __func__);
+
+	if (num_buffers == NULL || num_planes == NULL)
+		return -EINVAL;
+
+	*num_planes = 1;
+	/*MDP outputs in RGB for now;i
+	 * make sure it's smaller than VIDEO_MAX_PLANES*/
+	sizes[0] = 800*480*2;
+
+	return 0;
+}
+
+void wfd_vidbuf_wait_prepare(struct vb2_queue *q)
+{
+}
+void wfd_vidbuf_wait_finish(struct vb2_queue *q)
+{
+}
+
+int wfd_vidbuf_buf_init(struct vb2_buffer *vb)
+{
+	int rc = 0;
+	struct vb2_queue *q = vb->vb2_queue;
+	struct file *priv_data = (struct file *)(q->drv_priv);
+	struct wfd_inst *inst = (struct wfd_inst *)priv_data->private_data;
+	struct wfd_device *wfd_dev =
+		(struct wfd_device *)video_drvdata(priv_data);
+	struct mdp_buf_info buf = {
+					inst->mdp_inst,
+					vb,
+					inst->minfo[vb->v4l2_buf.index]->fd,
+					inst->minfo[vb->v4l2_buf.index]->offset
+					};
+
+	if (inst && !inst->vid_bufq.streaming) {
+		rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core,
+				ioctl, MDP_PREPARE_BUF, (void *)&buf);
+		if (rc)
+			WFD_MSG_ERR("Unable to prepare/register the buffer\n");
+	}
+	return rc;
+}
+
+int wfd_vidbuf_buf_prepare(struct vb2_buffer *vb)
+{
+	return 0;
+}
+
+int wfd_vidbuf_buf_finish(struct vb2_buffer *vb)
+{
+	return 0;
+}
+
+void wfd_vidbuf_buf_cleanup(struct vb2_buffer *vb)
+{
+	int rc = 0;
+	struct vb2_queue *q = vb->vb2_queue;
+	struct file *priv_data = (struct file *)(q->drv_priv);
+	struct wfd_device *wfd_dev =
+		(struct wfd_device *)video_drvdata(priv_data);
+	struct wfd_inst *inst = (struct wfd_inst *)priv_data->private_data;
+	struct mdp_buf_info buf = {
+					inst->mdp_inst,
+					vb,
+					inst->minfo[vb->v4l2_buf.index]->fd,
+					inst->minfo[vb->v4l2_buf.index]->offset
+					};
+	WFD_MSG_DBG("Releasing buffer\n");
+	rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl,
+			 MDP_RELEASE_BUF, (void *)&buf);
+	if (rc)
+		WFD_MSG_ERR("Failed to release the buffer\n");
+}
+
+int wfd_vidbuf_start_streaming(struct vb2_queue *q)
+{
+	struct file *priv_data = (struct file *)(q->drv_priv);
+	struct wfd_device *wfd_dev =
+		(struct wfd_device *)video_drvdata(priv_data);
+	struct wfd_inst *inst = (struct wfd_inst *)priv_data->private_data;
+	int rc = 0;
+	rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl,
+			 MDP_START, (void *)inst->mdp_inst);
+	if (rc)
+		WFD_MSG_ERR("Failed to start MDP\n");
+
+	return rc;
+}
+
+int wfd_vidbuf_stop_streaming(struct vb2_queue *q)
+{
+	struct file *priv_data = (struct file *)(q->drv_priv);
+	struct wfd_device *wfd_dev =
+		(struct wfd_device *)video_drvdata(priv_data);
+	struct wfd_inst *inst = (struct wfd_inst *)priv_data->private_data;
+	int rc = 0;
+	rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl,
+			 MDP_STOP, (void *)inst->mdp_inst);
+	if (rc)
+		WFD_MSG_ERR("Failed to stop MDP\n");
+
+	return rc;
+}
+
+void wfd_vidbuf_buf_queue(struct vb2_buffer *vb)
+{
+	int rc = 0;
+	struct vb2_queue *q = vb->vb2_queue;
+	struct file *priv_data = (struct file *)(q->drv_priv);
+	struct wfd_device *wfd_dev =
+		(struct wfd_device *)video_drvdata(priv_data);
+	struct wfd_inst *inst = (struct wfd_inst *)priv_data->private_data;
+	struct mdp_buf_info buf = {
+					inst->mdp_inst,
+					vb,
+					inst->minfo[vb->v4l2_buf.index]->fd,
+					inst->minfo[vb->v4l2_buf.index]->offset
+					};
+
+	WFD_MSG_DBG("Inside wfd_vidbuf_queue\n");
+	rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl,
+			MDP_Q_BUFFER, (void *)&buf);
+	if (rc)
+		WFD_MSG_ERR("Failed to call fill this buffer\n");
+}
+
+static struct vb2_ops wfd_vidbuf_ops = {
+	.queue_setup = wfd_vidbuf_queue_setup,
+
+	.wait_prepare = wfd_vidbuf_wait_prepare,
+	.wait_finish = wfd_vidbuf_wait_finish,
+
+	.buf_init = wfd_vidbuf_buf_init,
+	.buf_prepare = wfd_vidbuf_buf_prepare,
+	.buf_finish = wfd_vidbuf_buf_finish,
+	.buf_cleanup = wfd_vidbuf_buf_cleanup,
+
+	.start_streaming = wfd_vidbuf_start_streaming,
+	.stop_streaming = wfd_vidbuf_stop_streaming,
+
+	.buf_queue = wfd_vidbuf_buf_queue,
+
+};
+
+static const struct v4l2_subdev_core_ops mdp_subdev_core_ops = {
+	.init = mdp_init,
+	.ioctl = mdp_ioctl,
+};
+static const struct v4l2_subdev_ops mdp_subdev_ops = {
+	.core = &mdp_subdev_core_ops,
+};
+static int wfdioc_querycap(struct file *filp, void *fh,
+		struct v4l2_capability *cap) {
+	WFD_MSG_DBG("wfdioc_querycap: E\n");
+	memset(cap, 0, sizeof(struct v4l2_capability));
+	strlcpy(cap->driver, "wifi-display", sizeof(cap->driver));
+	strlcpy(cap->card, "msm", sizeof(cap->card));
+	cap->version = WFD_VERSION;
+	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+	WFD_MSG_DBG("wfdioc_querycap: X\n");
+	return 0;
+}
+static int wfdioc_g_fmt(struct file *filp, void *fh,
+			struct v4l2_format *fmt)
+{
+	struct wfd_inst *inst = filp->private_data;
+	unsigned long flags;
+	if (!fmt) {
+		WFD_MSG_ERR("Invalid argument\n");
+		return -EINVAL;
+	}
+	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		WFD_MSG_ERR("Only V4L2_BUF_TYPE_VIDEO_CAPTURE is supported\n");
+		return -EINVAL;
+	}
+	spin_lock_irqsave(&inst->inst_lock, flags);
+	fmt->fmt.pix.width = inst->width;
+	fmt->fmt.pix.height = inst->height;
+	fmt->fmt.pix.pixelformat = inst->pixelformat;
+	fmt->fmt.pix.sizeimage = inst->width * inst->height * 2;
+	fmt->fmt.pix.bytesperline = inst->width * 2; /*TODO: Needs
+							discussion */
+	fmt->fmt.pix.field = V4L2_FIELD_NONE;
+	fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; /*TODO: Needs
+							discussion*/
+	fmt->fmt.pix.priv = 0;
+	spin_unlock_irqrestore(&inst->inst_lock, flags);
+	return 0;
+}
+static int wfdioc_s_fmt(struct file *filp, void *fh,
+			struct v4l2_format *fmt)
+{
+	int rc = 0;
+	struct wfd_inst *inst = filp->private_data;
+	struct wfd_device *wfd_dev = video_drvdata(filp);
+	struct mdp_prop prop;
+	unsigned long flags;
+	if (!fmt) {
+		WFD_MSG_ERR("Invalid argument\n");
+		return -EINVAL;
+	}
+
+	if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+		fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_RGB565) {
+		WFD_MSG_ERR("Only V4L2_BUF_TYPE_VIDEO_CAPTURE and "
+				"V4L2_PIX_FMT_RGB565 are supported\n");
+		return -EINVAL;
+	}
+	spin_lock_irqsave(&inst->inst_lock, flags);
+	prop.height = inst->height = fmt->fmt.pix.height;
+	prop.width = inst->width = fmt->fmt.pix.width;
+	prop.inst = inst->mdp_inst;
+	fmt->fmt.pix.sizeimage = inst->height * inst->width * 2;
+	fmt->fmt.pix.field = V4L2_FIELD_NONE;
+	fmt->fmt.pix.bytesperline = inst->width * 2; /*TODO: Needs
+							 discussion */
+	fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; /*TODO: Needs
+						      discussion*/
+	spin_unlock_irqrestore(&inst->inst_lock, flags);
+	rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl, MDP_SET_PROP,
+				(void *)&prop);
+	if (rc)
+		WFD_MSG_ERR("Failed to set height/width property on mdp\n");
+	return rc;
+}
+static int wfdioc_reqbufs(struct file *filp, void *fh,
+		struct v4l2_requestbuffers *b)
+{
+	int rc = 0;
+	struct wfd_inst *inst = filp->private_data;
+	unsigned long flags;
+	int i;
+	if (b->type != V4L2_CAP_VIDEO_CAPTURE ||
+		b->memory != V4L2_MEMORY_USERPTR) {
+		WFD_MSG_ERR("Only V4L2_CAP_VIDEO_CAPTURE and "
+		"V4L2_CAP_VIDEO_CAPTURE are supported\n");
+		return -EINVAL;
+	}
+	if (b->count < MIN_BUF_COUNT)
+		b->count = MIN_BUF_COUNT;
+	spin_lock_irqsave(&inst->inst_lock, flags);
+	if (inst->minfo) {
+		for (i = 0; i < inst->buf_count; ++i)
+			kfree(inst->minfo[i]);
+	}
+	kfree(inst->minfo);
+	inst->buf_count = b->count;
+	inst->minfo = kzalloc(sizeof(struct mem_info *) * inst->buf_count,
+						GFP_KERNEL);
+	for (i = 0; i < inst->buf_count; ++i)
+		inst->minfo[i] = kzalloc(sizeof(struct mem_info), GFP_KERNEL);
+	spin_unlock_irqrestore(&inst->inst_lock, flags);
+	rc = vb2_reqbufs(&inst->vid_bufq, b);
+	if (rc) {
+		WFD_MSG_ERR("Failed in videobuf_reqbufs, rc = %d\n", rc);
+		spin_lock_irqsave(&inst->inst_lock, flags);
+		if (inst->minfo) {
+			for (i = 0; i < inst->buf_count; ++i)
+				kfree(inst->minfo[i]);
+		}
+		kfree(inst->minfo);
+		inst->minfo = NULL;
+		spin_unlock_irqrestore(&inst->inst_lock, flags);
+	}
+	return rc;
+}
+static int wfdioc_qbuf(struct file *filp, void *fh,
+		struct v4l2_buffer *b)
+{
+	int rc = 0;
+	struct wfd_inst *inst = filp->private_data;
+
+	if (!inst || !b || !b->reserved ||
+			(b->index < 0 || b->index >= inst->buf_count)) {
+		WFD_MSG_ERR("Invalid input parameters to QBUF IOCTL\n");
+		return -EINVAL;
+	}
+	if (!inst->vid_bufq.streaming) {
+		if (copy_from_user(inst->minfo[b->index], (void *)b->reserved,
+				sizeof(struct mem_info))) {
+			WFD_MSG_ERR(" copy_from_user failed. Populate"
+						" v4l2_buffer->reserved with meminfo\n");
+			return -EINVAL;
+		}
+	}
+	rc = vb2_qbuf(&inst->vid_bufq, b);
+	if (rc)
+		WFD_MSG_ERR("Failed to queue buffer\n");
+	return rc;
+}
+static int mdp_output_thread(void *data)
+{
+	int rc = 0;
+	struct file *filp = (struct file *)data;
+	struct wfd_inst *inst = filp->private_data;
+	struct wfd_device *wfd_dev =
+		(struct wfd_device *)video_drvdata(filp);
+	struct vb2_buffer *vbuf = NULL;
+	struct mdp_buf_info obuf = {inst->mdp_inst, vbuf, 0, 0};
+	while (!kthread_should_stop()) {
+		rc = v4l2_subdev_call(&wfd_dev->mdp_sdev,
+			core, ioctl, MDP_DQ_BUFFER, (void *)&obuf);
+
+		if (rc) {
+			WFD_MSG_ERR("Either streamoff called or"
+						" MDP REPORTED ERROR\n");
+			break;
+		} else
+			WFD_MSG_DBG("Dequeued buffer successfully\n");
+
+		vbuf = obuf.b;
+		vb2_buffer_done(vbuf,
+			rc ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
+	}
+	WFD_MSG_DBG("Exiting the thread\n");
+	return rc;
+}
+static int wfdioc_streamon(struct file *filp, void *fh,
+		enum v4l2_buf_type i)
+{
+	int rc = 0;
+	struct wfd_inst *inst = filp->private_data;
+	unsigned long flags;
+	if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		WFD_MSG_ERR("stream on for buffer type = %d is not "
+			"supported.\n", i);
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&inst->inst_lock, flags);
+	inst->streamoff = false;
+	spin_unlock_irqrestore(&inst->inst_lock, flags);
+	/*TODO: Do we need to lock the instance here*/
+	rc = vb2_streamon(&inst->vid_bufq, i);
+	if (rc) {
+		WFD_MSG_ERR("videobuf_streamon failed with err = %d\n", rc);
+		goto vidbuf_streamon_failed;
+	}
+	inst->mdp_task = kthread_run(mdp_output_thread, filp,
+				"mdp_output_thread");
+	if (IS_ERR(inst->mdp_task)) {
+		rc = PTR_ERR(inst->mdp_task);
+		goto mdp_task_failed;
+	}
+	return rc;
+mdp_task_failed:
+	vb2_streamoff(&inst->vid_bufq, i);
+vidbuf_streamon_failed:
+	return rc;
+}
+static int wfdioc_streamoff(struct file *filp, void *fh,
+		enum v4l2_buf_type i)
+{
+	struct wfd_inst *inst = filp->private_data;
+	unsigned long flags;
+	spin_lock_irqsave(&inst->inst_lock, flags);
+	if (inst->streamoff) {
+		WFD_MSG_ERR("Module is already in streamoff state\n");
+		spin_unlock_irqrestore(&inst->inst_lock, flags);
+		return -EINVAL;
+	}
+	inst->streamoff = true;
+	spin_unlock_irqrestore(&inst->inst_lock, flags);
+	if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		WFD_MSG_ERR("stream off for buffer type = %d is not "
+			"supported.\n", i);
+		return -EINVAL;
+	}
+	WFD_MSG_DBG("Calling videobuf_streamoff\n");
+	vb2_streamoff(&inst->vid_bufq, i);
+	vb2_queue_release(&inst->vid_bufq);
+	kthread_stop(inst->mdp_task);
+	return 0;
+}
+static int wfdioc_dqbuf(struct file *filp, void *fh,
+		struct v4l2_buffer *b)
+{
+	struct wfd_inst *inst = filp->private_data;
+	WFD_MSG_INFO("Waiting to dequeue buffer\n");
+	return vb2_dqbuf(&inst->vid_bufq, b, 0);
+}
+static const struct v4l2_ioctl_ops g_wfd_ioctl_ops = {
+	.vidioc_querycap = wfdioc_querycap,
+	.vidioc_s_fmt_vid_cap = wfdioc_s_fmt,
+	.vidioc_g_fmt_vid_cap = wfdioc_g_fmt,
+	.vidioc_reqbufs = wfdioc_reqbufs,
+	.vidioc_qbuf = wfdioc_qbuf,
+	.vidioc_streamon = wfdioc_streamon,
+	.vidioc_streamoff = wfdioc_streamoff,
+	.vidioc_dqbuf = wfdioc_dqbuf,
+};
+static int wfd_set_default_properties(struct wfd_inst *inst)
+{
+	unsigned long flags;
+	if (!inst) {
+		WFD_MSG_ERR("Invalid argument\n");
+		return -EINVAL;
+	}
+	spin_lock_irqsave(&inst->inst_lock, flags);
+	inst->height = DEFAULT_WFD_HEIGHT;
+	inst->width = DEFAULT_WFD_WIDTH;
+	inst->pixelformat = V4L2_PIX_FMT_RGB565;
+	spin_unlock_irqrestore(&inst->inst_lock, flags);
+	return 0;
+}
+static int wfd_open(struct file *filp)
+{
+	int rc = 0;
+	struct wfd_inst *inst;
+	struct wfd_device *wfd_dev;
+	WFD_MSG_DBG("wfd_open: E\n");
+	inst = kzalloc(sizeof(struct wfd_inst), GFP_KERNEL);
+	if (!inst) {
+		WFD_MSG_ERR("Could not allocate memory for "
+			"wfd instance\n");
+		return -ENOMEM;
+	}
+	spin_lock_init(&inst->inst_lock);
+	spin_lock_init(&inst->buflock);
+	wfd_dev = video_drvdata(filp);
+	rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl, MDP_OPEN,
+				(void *)&inst->mdp_inst);
+	if (rc) {
+		WFD_MSG_ERR("Failed to open mdp subdevice: %d\n", rc);
+		goto err_mdp_open;
+	}
+
+	videobuf2_queue_pmem_contig_init(&inst->vid_bufq,
+				V4L2_BUF_TYPE_VIDEO_CAPTURE,
+				&wfd_vidbuf_ops,
+				sizeof(struct wfd_vid_buffer),
+				filp);  /*TODO: Check if it needs to be freed*/
+	wfd_set_default_properties(inst);
+	filp->private_data = inst;
+	WFD_MSG_DBG("wfd_open: X\n");
+	return rc;
+err_mdp_open:
+	kfree(inst);
+	return rc;
+}
+static int wfd_close(struct file *filp)
+{
+	struct wfd_inst *inst;
+	struct wfd_device *wfd_dev;
+	int rc = 0;
+	int k;
+	unsigned long flags;
+	wfd_dev = video_drvdata(filp);
+	WFD_MSG_DBG("wfd_close: E\n");
+	inst = filp->private_data;
+	if (inst) {
+		wfdioc_streamoff(filp, NULL, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+		rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core, ioctl,
+				MDP_CLOSE, (void *)inst->mdp_inst);
+		if (rc)
+			WFD_MSG_ERR("Failed to CLOSE mdp subdevice: %d\n", rc);
+		spin_lock_irqsave(&inst->inst_lock, flags);
+		if (inst->minfo) {
+			for (k = 0; k < inst->buf_count; ++k)
+				kfree(inst->minfo[k]);
+		}
+		kfree(inst->minfo);
+		inst->minfo = NULL;
+		spin_unlock_irqrestore(&inst->inst_lock, flags);
+		kfree(inst);
+	}
+	WFD_MSG_DBG("wfd_close: X\n");
+	return 0;
+}
+static const struct v4l2_file_operations g_wfd_fops = {
+	.owner = THIS_MODULE,
+	.open = wfd_open,
+	.release = wfd_close,
+	.ioctl = video_ioctl2
+};
+void release_video_device(struct video_device *pvdev)
+{
+
+}
+static int __devinit __wfd_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct wfd_device *wfd_dev;
+	WFD_MSG_DBG("__wfd_probe: E\n");
+	wfd_dev = kzalloc(sizeof(*wfd_dev), GFP_KERNEL);  /*TODO: Free it*/
+	if (!wfd_dev) {
+		WFD_MSG_ERR("Could not allocate memory for "
+				"wfd device\n");
+		return -ENOMEM;
+	}
+	pdev->dev.platform_data = (void *) wfd_dev;
+	rc = v4l2_device_register(&pdev->dev, &wfd_dev->v4l2_dev);
+	if (rc) {
+		WFD_MSG_ERR("Failed to register the video device\n");
+		goto err_v4l2_registration;
+	}
+	wfd_dev->pvdev = video_device_alloc();
+	if (!wfd_dev->pvdev) {
+		WFD_MSG_ERR("Failed to allocate video device\n");
+		goto err_video_device_alloc;
+	}
+
+	wfd_dev->pvdev->release = release_video_device;
+	wfd_dev->pvdev->fops = &g_wfd_fops;
+	wfd_dev->pvdev->ioctl_ops = &g_wfd_ioctl_ops;
+
+	rc = video_register_device(wfd_dev->pvdev, VFL_TYPE_GRABBER, -1);
+	if (rc) {
+		WFD_MSG_ERR("Failed to register the device\n");
+		goto err_video_register_device;
+	}
+	video_set_drvdata(wfd_dev->pvdev, wfd_dev);
+
+	v4l2_subdev_init(&wfd_dev->mdp_sdev, &mdp_subdev_ops);
+	strncpy(wfd_dev->mdp_sdev.name, "wfd-mdp", V4L2_SUBDEV_NAME_SIZE);
+	rc = v4l2_device_register_subdev(&wfd_dev->v4l2_dev,
+						&wfd_dev->mdp_sdev);
+	if (rc) {
+		WFD_MSG_ERR("Failed to register mdp subdevice: %d\n", rc);
+		goto err_mdp_register_subdev;
+	}
+	WFD_MSG_DBG("__wfd_probe: X\n");
+	return rc;
+err_mdp_register_subdev:
+	video_unregister_device(wfd_dev->pvdev);
+err_video_register_device:
+	video_device_release(wfd_dev->pvdev);
+err_video_device_alloc:
+	v4l2_device_unregister(&wfd_dev->v4l2_dev);
+err_v4l2_registration:
+	kfree(wfd_dev);
+	return rc;
+}
+
+static int __devexit __wfd_remove(struct platform_device *pdev)
+{
+	struct wfd_device *wfd_dev;
+	wfd_dev = (struct wfd_device *)pdev->dev.platform_data;
+
+	WFD_MSG_DBG("Inside wfd_remove\n");
+	if (!wfd_dev) {
+		WFD_MSG_ERR("Error removing WFD device");
+		return -ENODEV;
+	}
+
+	v4l2_device_unregister_subdev(&wfd_dev->mdp_sdev);
+	video_unregister_device(wfd_dev->pvdev);
+	video_device_release(wfd_dev->pvdev);
+	v4l2_device_unregister(&wfd_dev->v4l2_dev);
+	kfree(wfd_dev);
+	return 0;
+}
+static struct platform_driver wfd_driver = {
+	.probe =  __wfd_probe,
+	.remove = __wfd_remove,
+	.driver = {
+		.name = "msm_wfd",
+		.owner = THIS_MODULE,
+	}
+};
+
+static int __init wfd_init(void)
+{
+	int rc = 0;
+	WFD_MSG_DBG("Calling init function of wfd driver\n");
+	rc = platform_driver_register(&wfd_driver);
+	if (rc) {
+		WFD_MSG_ERR("failed to load the driver\n");
+		goto err_platform_registration;
+	}
+err_platform_registration:
+	return rc;
+}
+
+static void __exit wfd_exit(void)
+{
+	WFD_MSG_DBG("wfd_exit: X\n");
+	platform_driver_unregister(&wfd_driver);
+}
+
+module_init(wfd_init);
+module_exit(wfd_exit);
diff --git a/drivers/media/video/msm/wfd/wfd-util.h b/drivers/media/video/msm/wfd/wfd-util.h
new file mode 100644
index 0000000..038a2cb
--- /dev/null
+++ b/drivers/media/video/msm/wfd/wfd-util.h
@@ -0,0 +1,30 @@
+/* Copyright (c) 2011, 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
+ * 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 _WFD_UTIL_H_
+#define _WFD_UTIL_H_
+
+/*#define DEBUG_WFD*/
+
+#ifdef DEBUG_WFD
+	#define WFD_MSG_INFO(fmt...) pr_info(fmt)
+	#define WFD_MSG_WARN(fmt...) pr_warning(fmt)
+	#define WFD_MSG_DBG(fmt...) pr_debug(fmt)
+#else
+	#define WFD_MSG_INFO(fmt...)
+	#define WFD_MSG_WARN(fmt...)
+	#define WFD_MSG_DBG(fmt...)
+#endif
+	#define WFD_MSG_ERR(fmt...) pr_err(KERN_ERR fmt)
+	#define WFD_MSG_CRIT(fmt...) pr_crit(KERN_CRIT fmt)
+#endif
diff --git a/drivers/media/video/videobuf2-msm-mem.c b/drivers/media/video/videobuf2-msm-mem.c
index d765244..fa7e3fd 100644
--- a/drivers/media/video/videobuf2-msm-mem.c
+++ b/drivers/media/video/videobuf2-msm-mem.c
@@ -151,16 +151,27 @@
 int videobuf2_pmem_contig_user_get(struct videobuf2_contig_pmem *mem,
 					struct videobuf2_msm_offset *offset,
 					enum videobuf2_buffer_type buffer_type,
-					uint32_t addr_offset, int path)
+					uint32_t addr_offset, int path,
+					struct ion_client *client)
 {
-	unsigned long kvstart;
 	unsigned long len;
-	int rc;
+	int rc = 0;
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
+	unsigned long kvstart;
+#endif
 	unsigned int flags = 0;
-
+	unsigned long paddr = 0;
 	if (mem->phyaddr != 0)
 		return 0;
-
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	mem->ion_handle = ion_import_fd(client, (int)mem->vaddr);
+	if (IS_ERR_OR_NULL(mem->ion_handle)) {
+		pr_err("%s ION import failed\n", __func__);
+		return PTR_ERR(mem->ion_handle);
+	}
+	rc = ion_phys(client, mem->ion_handle, (ion_phys_addr_t *)&mem->phyaddr,
+			 (size_t *)&len);
+#elif CONFIG_ANDROID_PMEM
 	rc = get_pmem_file((int)mem->vaddr, (unsigned long *)&mem->phyaddr,
 					&kvstart, &len, &mem->file);
 	if (rc < 0) {
@@ -168,32 +179,48 @@
 					__func__, (int)mem->vaddr, rc);
 		return rc;
 	}
+#else
+	paddr = 0;
+	kvstart = 0;
+#endif
 	if (offset)
 		mem->offset = *offset;
 	else
 		memset(&mem->offset, 0, sizeof(struct videobuf2_msm_offset));
 	mem->path = path;
 	mem->buffer_type = buffer_type;
+	paddr = mem->phyaddr;
 	flags = MSM_SUBSYSTEM_MAP_IOVA;
 	mem->subsys_id = MSM_SUBSYSTEM_CAMERA;
 	mem->msm_buffer = msm_subsystem_map_buffer(mem->phyaddr, len,
 					flags, &(mem->subsys_id), 1);
 	if (IS_ERR((void *)mem->msm_buffer)) {
 		pr_err("%s: msm_subsystem_map_buffer failed\n", __func__);
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+		ion_free(client, mem->ion_handle);
+#elif CONFIG_ANDROID_PMEM
 		put_pmem_file(mem->file);
+#endif
 		return PTR_ERR((void *)mem->msm_buffer);
 	}
-	mem->mapped_phyaddr = mem->msm_buffer->iova[0] + addr_offset;
+	paddr = mem->msm_buffer->iova[0];
+	mem->mapped_phyaddr = paddr + addr_offset;
 	return rc;
 }
 EXPORT_SYMBOL_GPL(videobuf2_pmem_contig_user_get);
 
-void videobuf2_pmem_contig_user_put(struct videobuf2_contig_pmem *mem)
+void videobuf2_pmem_contig_user_put(struct videobuf2_contig_pmem *mem,
+					struct ion_client *client)
 {
 	if (msm_subsystem_unmap_buffer(mem->msm_buffer) < 0)
 		D("%s unmapped memory\n", __func__);
-	if (mem->is_userptr)
+	if (mem->is_userptr) {
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+		ion_free(client, mem->ion_handle);
+#elif CONFIG_ANDROID_PMEM
 		put_pmem_file(mem->file);
+#endif
+	}
 	mem->is_userptr = 0;
 	mem->phyaddr = 0;
 	mem->size = 0;
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 6181758..e639815 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -1024,8 +1024,6 @@
 
 	if (data->flags & MMC_DATA_READ)
 		datactrl |= (MCI_DPSM_DIRECTION | MCI_RX_DATA_PEND);
-	else if (data->flags & MMC_DATA_WRITE)
-		datactrl |= MCI_DATA_PEND;
 
 	clks = (unsigned long long)data->timeout_ns * host->clk_rate;
 	do_div(clks, 1000000000UL);
@@ -1364,6 +1362,9 @@
 			msmsdcc_start_command(host, host->curr.mrq->cmd, 0);
 		else
 			msmsdcc_request_start(host, host->curr.mrq);
+	} else if (cmd->data) {
+		if (!(cmd->data->flags & MMC_DATA_READ))
+			msmsdcc_start_data(host, cmd->data, NULL, 0);
 	}
 }
 
@@ -1570,9 +1571,9 @@
 static void
 msmsdcc_request_start(struct msmsdcc_host *host, struct mmc_request *mrq)
 {
-	if (mrq->data) {
+	if (mrq->data && mrq->data->flags & MMC_DATA_READ) {
 		/* Queue/read data, daisy-chain command when data starts */
-		if (mrq->sbc && (mrq->data->flags & MMC_DATA_READ))
+		if (mrq->sbc)
 			msmsdcc_start_data(host, mrq->data, mrq->sbc, 0);
 		else
 			msmsdcc_start_data(host, mrq->data, mrq->cmd, 0);
@@ -2489,7 +2490,7 @@
 	usleep_range(5000, 5500);
 
 	spin_lock_irqsave(&host->lock, flags);
-	/* Start SD CLK output. */
+	/* Disable PWRSAVE would make sure that SD CLK is always running */
 	writel_relaxed((readl_relaxed(host->base + MMCICLOCK)
 			& ~MCI_CLK_PWRSAVE), host->base + MMCICLOCK);
 	msmsdcc_delay(host);
@@ -2513,6 +2514,9 @@
 	}
 
 out_unlock:
+	/* Enable PWRSAVE */
+	writel_relaxed((readl_relaxed(host->base + MMCICLOCK) |
+			MCI_CLK_PWRSAVE), host->base + MMCICLOCK);
 	spin_unlock_irqrestore(&host->lock, flags);
 out:
 	return rc;
@@ -3523,9 +3527,10 @@
 	if (pdev->id < 1 || pdev->id > 5)
 		return -EINVAL;
 
-	if (plat->is_sdio_al_client)
-		if (!plat->sdio_lpm_gpio_setup || !plat->sdiowakeup_irq)
-			return -EINVAL;
+	if (plat->is_sdio_al_client && !plat->sdiowakeup_irq) {
+		pr_err("%s: No wakeup IRQ for sdio_al client\n", __func__);
+		return -EINVAL;
+	}
 
 	if (pdev->resource == NULL || pdev->num_resources < 2) {
 		pr_err("%s: Invalid resource\n", __func__);
@@ -4095,7 +4100,8 @@
 			host->clks_on = 0;
 		}
 
-		if (!host->sdio_gpio_lpm) {
+		if (host->plat->sdio_lpm_gpio_setup &&
+				!host->sdio_gpio_lpm) {
 			spin_unlock_irqrestore(&host->lock, flags);
 			host->plat->sdio_lpm_gpio_setup(mmc_dev(mmc), 0);
 			spin_lock_irqsave(&host->lock, flags);
@@ -4114,7 +4120,8 @@
 			msmsdcc_disable_irq_wake(host);
 		}
 
-		if (host->sdio_gpio_lpm) {
+		if (host->plat->sdio_lpm_gpio_setup &&
+				host->sdio_gpio_lpm) {
 			spin_unlock_irqrestore(&host->lock, flags);
 			host->plat->sdio_lpm_gpio_setup(mmc_dev(mmc), 1);
 			spin_lock_irqsave(&host->lock, flags);
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index 590c293..12aa54b 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -77,7 +77,6 @@
 #define MCI_DPSM_DIRECTION	(1 << 1)
 #define MCI_DPSM_MODE		(1 << 2)
 #define MCI_DPSM_DMAENABLE	(1 << 3)
-#define MCI_DATA_PEND		(1 << 17)
 #define MCI_AUTO_PROG_DONE	(1 << 19)
 #define MCI_RX_DATA_PEND	(1 << 20)
 
diff --git a/drivers/net/msm_rmnet_bam.c b/drivers/net/msm_rmnet_bam.c
index aeb85dc..e617aa5 100644
--- a/drivers/net/msm_rmnet_bam.c
+++ b/drivers/net/msm_rmnet_bam.c
@@ -737,8 +737,11 @@
 		bam_rmnet_drivers[n].driver.name = tempname;
 		bam_rmnet_drivers[n].driver.owner = THIS_MODULE;
 		ret = platform_driver_register(&bam_rmnet_drivers[n]);
-		if (!ret)
+		if (ret) {
+			pr_err("%s: registration failed n=%d rc=%d\n",
+					__func__, n, ret);
 			return ret;
+		}
 	}
 	return 0;
 }
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index 1064aa0..a3c32b9 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -2192,7 +2192,7 @@
 
 	retval = request_any_context_irq(dev->irq, smsc911x_irqhandler,
 			     irq_flags | IRQF_SHARED, dev->name, dev);
-	if (retval) {
+	if (retval < 0) {
 		SMSC_WARN(pdata, probe,
 			  "Unable to claim requested irq: %d", dev->irq);
 		goto out_unmap_io_3;
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index c16632e..1c56f34 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -27,7 +27,6 @@
 #define DEVICE "wcnss_wlan"
 #define VERSION "1.01"
 #define WCNSS_PIL_DEVICE "wcnss"
-#define WCNSS_NV_NAME "wlan/prima/WCNSS_qcom_cfg.ini"
 
 /* module params */
 #define WCNSS_CONFIG_UNSPECIFIED (-1)
diff --git a/drivers/power/isl9519q.c b/drivers/power/isl9519q.c
index 733de45..e4729f2 100644
--- a/drivers/power/isl9519q.c
+++ b/drivers/power/isl9519q.c
@@ -60,6 +60,8 @@
 	bool				trickle;
 };
 
+static struct isl9519q_struct *the_isl_chg;
+
 static int isl9519q_read_reg(struct i2c_client *client, int reg,
 	u16 *val)
 {
@@ -485,6 +487,71 @@
 
 	return 0;
 }
+static int set_reg(void *data, u64 val)
+{
+	int addr = (int)data;
+	int ret;
+	u16 temp;
+
+	temp = (u16) val;
+	ret = isl9519q_write_reg(the_isl_chg->client, addr, temp);
+
+	if (ret) {
+		pr_err("isl9519q_write_reg to %x value =%d errored = %d\n",
+			addr, temp, ret);
+		return -EAGAIN;
+	}
+	return 0;
+}
+static int get_reg(void *data, u64 *val)
+{
+	int addr = (int)data;
+	int ret;
+	u16 temp;
+
+	ret = isl9519q_read_reg(the_isl_chg->client, addr, &temp);
+	if (ret) {
+		pr_err("isl9519q_read_reg to %x value =%d errored = %d\n",
+			addr, temp, ret);
+		return -EAGAIN;
+	}
+
+	*val = temp;
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(reg_fops, get_reg, set_reg, "0x%02llx\n");
+
+static void create_debugfs_entries(struct isl9519q_struct *isl_chg)
+{
+	isl_chg->dent = debugfs_create_dir("isl9519q", NULL);
+
+	if (IS_ERR(isl_chg->dent)) {
+		pr_err("isl9519q driver couldn't create debugfs dir\n");
+		return;
+	}
+
+	debugfs_create_file("CHG_CURRENT_REG", 0644, isl_chg->dent,
+				(void *) CHG_CURRENT_REG, &reg_fops);
+	debugfs_create_file("MAX_SYS_VOLTAGE_REG", 0644, isl_chg->dent,
+				(void *) MAX_SYS_VOLTAGE_REG, &reg_fops);
+	debugfs_create_file("CONTROL_REG", 0644, isl_chg->dent,
+				(void *) CONTROL_REG, &reg_fops);
+	debugfs_create_file("MIN_SYS_VOLTAGE_REG", 0644, isl_chg->dent,
+				(void *) MIN_SYS_VOLTAGE_REG, &reg_fops);
+	debugfs_create_file("INPUT_CURRENT_REG", 0644, isl_chg->dent,
+				(void *) INPUT_CURRENT_REG, &reg_fops);
+	debugfs_create_file("MANUFACTURER_ID_REG", 0644, isl_chg->dent,
+				(void *) MANUFACTURER_ID_REG, &reg_fops);
+	debugfs_create_file("DEVICE_ID_REG", 0644, isl_chg->dent,
+				(void *) DEVICE_ID_REG, &reg_fops);
+}
+
+static void remove_debugfs_entries(struct isl9519q_struct *isl_chg)
+{
+	if (isl_chg->dent)
+		debugfs_remove_recursive(isl_chg->dent);
+}
 
 static int __devinit isl9519q_probe(struct i2c_client *client,
 				    const struct i2c_device_id *id)
@@ -582,6 +649,9 @@
 	if (ret)
 		goto free_isl_chg;
 
+	the_isl_chg = isl_chg;
+	create_debugfs_entries(isl_chg);
+
 	pr_info("%s OK.\n", __func__);
 
 	return 0;
@@ -603,6 +673,9 @@
 	cancel_delayed_work_sync(&isl_chg->charge_work);
 	msm_charger_notify_event(&isl_chg->adapter_hw_chg, CHG_REMOVED_EVENT);
 	msm_charger_unregister(&isl_chg->adapter_hw_chg);
+	remove_debugfs_entries(isl_chg);
+	the_isl_chg = NULL;
+	kfree(isl_chg);
 	return 0;
 }
 
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index 303dd99..dde6194 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -105,6 +105,39 @@
 	FSM_STATE_FLCB = 22,
 };
 
+struct fsm_state_to_batt_status {
+	enum chg_fsm_state	fsm_state;
+	int			batt_state;
+};
+
+static struct fsm_state_to_batt_status map[] = {
+	{FSM_STATE_OFF_0, POWER_SUPPLY_STATUS_UNKNOWN},
+	{FSM_STATE_BATFETDET_START_12, POWER_SUPPLY_STATUS_UNKNOWN},
+	{FSM_STATE_BATFETDET_END_16, POWER_SUPPLY_STATUS_UNKNOWN},
+	/*
+	 * for CHG_HIGHI_1 report NOT_CHARGING if battery missing,
+	 * too hot/cold, charger too hot
+	 */
+	{FSM_STATE_ON_CHG_HIGHI_1, POWER_SUPPLY_STATUS_FULL},
+	{FSM_STATE_ATC_2A, POWER_SUPPLY_STATUS_CHARGING},
+	{FSM_STATE_ATC_2B, POWER_SUPPLY_STATUS_CHARGING},
+	{FSM_STATE_ON_BAT_3, POWER_SUPPLY_STATUS_DISCHARGING},
+	{FSM_STATE_ATC_FAIL_4, POWER_SUPPLY_STATUS_DISCHARGING},
+	{FSM_STATE_DELAY_5, POWER_SUPPLY_STATUS_UNKNOWN },
+	{FSM_STATE_ON_CHG_AND_BAT_6, POWER_SUPPLY_STATUS_CHARGING},
+	{FSM_STATE_FAST_CHG_7, POWER_SUPPLY_STATUS_CHARGING},
+	{FSM_STATE_TRKL_CHG_8, POWER_SUPPLY_STATUS_CHARGING},
+	{FSM_STATE_CHG_FAIL_9, POWER_SUPPLY_STATUS_DISCHARGING},
+	{FSM_STATE_EOC_10, POWER_SUPPLY_STATUS_FULL},
+	{FSM_STATE_ON_CHG_VREGOK_11, POWER_SUPPLY_STATUS_NOT_CHARGING},
+	{FSM_STATE_ATC_PAUSE_13, POWER_SUPPLY_STATUS_NOT_CHARGING},
+	{FSM_STATE_FAST_CHG_PAUSE_14, POWER_SUPPLY_STATUS_NOT_CHARGING},
+	{FSM_STATE_TRKL_CHG_PAUSE_15, POWER_SUPPLY_STATUS_NOT_CHARGING},
+	{FSM_STATE_START_BOOT, POWER_SUPPLY_STATUS_NOT_CHARGING},
+	{FSM_STATE_FLCB_VREGOK, POWER_SUPPLY_STATUS_NOT_CHARGING},
+	{FSM_STATE_FLCB, POWER_SUPPLY_STATUS_NOT_CHARGING},
+};
+
 enum chg_regulation_loop {
 	VDD_LOOP = BIT(3),
 	BAT_CURRENT_LOOP = BIT(2),
@@ -968,36 +1001,22 @@
 
 static int get_prop_batt_status(struct pm8921_chg_chip *chip)
 {
-	int temp = 0;
+	int batt_state = POWER_SUPPLY_STATUS_DISCHARGING;
+	int fsm_state = pm_chg_get_fsm_state(chip);
+	int i;
 
-	if (!get_prop_batt_present(chip))
-		return POWER_SUPPLY_STATUS_UNKNOWN;
+	for (i = 0; i < ARRAY_SIZE(map); i++)
+		if (map[i].fsm_state == fsm_state)
+			batt_state = map[i].batt_state;
 
-	if (chip->ext) {
-		if (chip->ext_charge_done)
-			return POWER_SUPPLY_STATUS_FULL;
+	if (fsm_state == FSM_STATE_ON_CHG_HIGHI_1) {
+		if (!pm_chg_get_rt_status(chip, BATT_INSERTED_IRQ)
+			|| !pm_chg_get_rt_status(chip, BAT_TEMP_OK_IRQ)
+			|| !pm_chg_get_rt_status(chip, CHGHOT_IRQ))
 
-		if (chip->ext_charging)
-			return POWER_SUPPLY_STATUS_CHARGING;
+			batt_state = POWER_SUPPLY_STATUS_NOT_CHARGING;
 	}
-
-	/* TODO reading the FSM state is more reliable */
-	temp = pm_chg_get_rt_status(chip, TRKLCHG_IRQ);
-
-	temp |= pm_chg_get_rt_status(chip, FASTCHG_IRQ);
-	if (temp)
-		return POWER_SUPPLY_STATUS_CHARGING;
-	/*
-	 * The battery is not charging
-	 * check the FET - if on battery is discharging
-	 *		 - if off battery is isolated(full) and the system
-	 *		   is being driven from a charger
-	 */
-	temp = pm_chg_get_rt_status(chip, BATFET_IRQ);
-	if (temp)
-		return POWER_SUPPLY_STATUS_DISCHARGING;
-
-	return POWER_SUPPLY_STATUS_FULL;
+	return batt_state;
 }
 
 static int get_prop_batt_temp(struct pm8921_chg_chip *chip)
@@ -2329,6 +2348,9 @@
 		pm8xxx_writeb(chip->dev->parent, PSI_CONFIG_STATUS, 0x0C);
 	}
 
+	/* Disable EOC FSM processing */
+	pm8xxx_writeb(chip->dev->parent, CHG_BUCK_CTRL_TEST3, 0x91);
+
 	rc = pm_chg_charge_dis(chip, charging_disabled);
 	if (rc) {
 		pr_err("Failed to disable CHG_CHARGE_DIS bit rc=%d\n", rc);
diff --git a/drivers/thermal/pmic8058-tm.c b/drivers/thermal/pmic8058-tm.c
index cc98f37..2589494 100644
--- a/drivers/thermal/pmic8058-tm.c
+++ b/drivers/thermal/pmic8058-tm.c
@@ -351,7 +351,6 @@
 
 static int __devinit pmic8058_tm_probe(struct platform_device *pdev)
 {
-	DECLARE_COMPLETION_ONSTACK(wait);
 	struct pm8058_tm_device *tmdev;
 	struct pm8058_chip *pm_chip;
 	unsigned int irq;
@@ -382,10 +381,6 @@
 		return rc;
 	}
 
-	/* calibrate the die temperature sensor */
-	if (adc_calib_request(tmdev->adc_handle, &wait) == CALIB_STARTED)
-		wait_for_completion(&wait);
-
 	tmdev->pm_chip = pm_chip;
 	tmdev->tz_dev = thermal_zone_device_register("pm8058_tz",
 						     PM8058_TRIP_NUM, tmdev,
diff --git a/drivers/usb/gadget/u_bam.c b/drivers/usb/gadget/u_bam.c
index 73407bd..1de8fc1 100644
--- a/drivers/usb/gadget/u_bam.c
+++ b/drivers/usb/gadget/u_bam.c
@@ -33,37 +33,37 @@
 
 static const char *bam_ch_names[] = { "bam_dmux_ch_8" };
 
-#define TX_PKT_DROP_THRESHOLD			1000
-#define RX_PKT_FLOW_CTRL_EN_THRESHOLD		1000
-#define RX_PKT_FLOW_CTRL_DISABLE		500
-#define RX_PKT_FLOW_CTRL_SUPPORT		1
+#define BAM_MUX_TX_PKT_DROP_THRESHOLD		1000
+#define BAM_MUX_RX_PKT_FCTRL_EN_TSHOLD		200
+#define BAM_MUX_RX_PKT_FCTRL_DIS_TSHOLD		125
+#define BAM_MUX_RX_PKT_FLOW_CTRL_SUPPORT	1
 
 #define BAM_MUX_HDR				8
 
-#define RX_Q_SIZE				16
-#define TX_Q_SIZE				200
-#define RX_REQ_SIZE				(2048 - BAM_MUX_HDR)
+#define BAM_MUX_RX_Q_SIZE			16
+#define BAM_MUX_TX_Q_SIZE			200
+#define BAM_MUX_RX_REQ_SIZE			(2048 - BAM_MUX_HDR)
 
-unsigned int tx_pkt_drop_thld = TX_PKT_DROP_THRESHOLD;
-module_param(tx_pkt_drop_thld, uint, S_IRUGO | S_IWUSR);
+unsigned int bam_mux_tx_pkt_drop_thld = BAM_MUX_TX_PKT_DROP_THRESHOLD;
+module_param(bam_mux_tx_pkt_drop_thld, uint, S_IRUGO | S_IWUSR);
 
-unsigned int rx_fctrl_en_thld = RX_PKT_FLOW_CTRL_EN_THRESHOLD;
-module_param(rx_fctrl_en_thld, uint, S_IRUGO | S_IWUSR);
+unsigned int bam_mux_rx_fctrl_en_thld = BAM_MUX_RX_PKT_FCTRL_EN_TSHOLD;
+module_param(bam_mux_rx_fctrl_en_thld, uint, S_IRUGO | S_IWUSR);
 
-unsigned int rx_fctrl_support = RX_PKT_FLOW_CTRL_SUPPORT;
-module_param(rx_fctrl_support, uint, S_IRUGO | S_IWUSR);
+unsigned int bam_mux_rx_fctrl_support = BAM_MUX_RX_PKT_FLOW_CTRL_SUPPORT;
+module_param(bam_mux_rx_fctrl_support, uint, S_IRUGO | S_IWUSR);
 
-unsigned int rx_fctrl_dis_thld = RX_PKT_FLOW_CTRL_DISABLE;
-module_param(rx_fctrl_dis_thld, uint, S_IRUGO | S_IWUSR);
+unsigned int bam_mux_rx_fctrl_dis_thld = BAM_MUX_RX_PKT_FCTRL_DIS_TSHOLD;
+module_param(bam_mux_rx_fctrl_dis_thld, uint, S_IRUGO | S_IWUSR);
 
-unsigned int tx_q_size = TX_Q_SIZE;
-module_param(tx_q_size, uint, S_IRUGO | S_IWUSR);
+unsigned int bam_mux_tx_q_size = BAM_MUX_TX_Q_SIZE;
+module_param(bam_mux_tx_q_size, uint, S_IRUGO | S_IWUSR);
 
-unsigned int rx_q_size = RX_Q_SIZE;
-module_param(rx_q_size, uint, S_IRUGO | S_IWUSR);
+unsigned int bam_mux_rx_q_size = BAM_MUX_RX_Q_SIZE;
+module_param(bam_mux_rx_q_size, uint, S_IRUGO | S_IWUSR);
 
-unsigned int rx_req_size = RX_REQ_SIZE;
-module_param(rx_req_size, uint, S_IRUGO | S_IWUSR);
+unsigned int bam_mux_rx_req_size = BAM_MUX_RX_REQ_SIZE;
+module_param(bam_mux_rx_req_size, uint, S_IRUGO | S_IWUSR);
 
 #define BAM_CH_OPENED	BIT(0)
 #define BAM_CH_READY	BIT(1)
@@ -211,7 +211,7 @@
 		return;
 	}
 
-	if (d->tx_skb_q.qlen > tx_pkt_drop_thld) {
+	if (d->tx_skb_q.qlen > bam_mux_tx_pkt_drop_thld) {
 		d->tohost_drp_cnt++;
 		if (printk_ratelimit())
 			pr_err("%s: tx pkt dropped: tx_drop_cnt:%u\n",
@@ -246,8 +246,8 @@
 			port, d, d->to_modem,
 			d->pending_with_bam, port->port_num);
 
-	if (rx_fctrl_support &&
-			d->pending_with_bam >= rx_fctrl_dis_thld) {
+	if (bam_mux_rx_fctrl_support &&
+			d->pending_with_bam >= bam_mux_rx_fctrl_dis_thld) {
 
 		spin_unlock_irqrestore(&port->port_lock, flags);
 		return;
@@ -274,7 +274,13 @@
 		return;
 	}
 
-	while ((skb = __skb_dequeue(&d->rx_skb_q))) {
+	while (!bam_mux_rx_fctrl_support ||
+			(d->pending_with_bam < bam_mux_rx_fctrl_en_thld)) {
+		skb =  __skb_dequeue(&d->rx_skb_q);
+		if (!skb) {
+			spin_unlock_irqrestore(&port->port_lock, flags);
+			return;
+		}
 		d->pending_with_bam++;
 		d->to_modem++;
 
@@ -370,8 +376,8 @@
 	/* TODO: Handle flow control gracefully by having
 	 * having call back mechanism from bam driver
 	 */
-	if (rx_fctrl_support &&
-		d->pending_with_bam >= rx_fctrl_en_thld) {
+	if (bam_mux_rx_fctrl_support &&
+		d->pending_with_bam >= bam_mux_rx_fctrl_en_thld) {
 
 		list_add_tail(&req->list, &d->rx_idle);
 		spin_unlock(&port->port_lock);
@@ -379,7 +385,7 @@
 	}
 	spin_unlock(&port->port_lock);
 
-	skb = alloc_skb(rx_req_size + BAM_MUX_HDR, GFP_ATOMIC);
+	skb = alloc_skb(bam_mux_rx_req_size + BAM_MUX_HDR, GFP_ATOMIC);
 	if (!skb) {
 		spin_lock(&port->port_lock);
 		list_add_tail(&req->list, &d->rx_idle);
@@ -389,7 +395,7 @@
 	skb_reserve(skb, BAM_MUX_HDR);
 
 	req->buf = skb->data;
-	req->length = rx_req_size;
+	req->length = bam_mux_rx_req_size;
 	req->context = skb;
 
 	status = usb_ep_queue(ep, req, GFP_ATOMIC);
@@ -427,14 +433,14 @@
 	while (port->port_usb && !list_empty(&d->rx_idle)) {
 		req = list_first_entry(&d->rx_idle, struct usb_request, list);
 
-		skb = alloc_skb(rx_req_size + BAM_MUX_HDR, GFP_ATOMIC);
+		skb = alloc_skb(bam_mux_rx_req_size + BAM_MUX_HDR, GFP_ATOMIC);
 		if (!skb)
 			break;
 		skb_reserve(skb, BAM_MUX_HDR);
 
 		list_del(&req->list);
 		req->buf = skb->data;
-		req->length = rx_req_size;
+		req->length = bam_mux_rx_req_size;
 		req->context = skb;
 
 		spin_unlock_irqrestore(&port->port_lock, flags);
@@ -473,7 +479,7 @@
 
 	d = &port->data_ch;
 	ep = port->port_usb->out;
-	ret = gbam_alloc_requests(ep, &d->rx_idle, rx_q_size,
+	ret = gbam_alloc_requests(ep, &d->rx_idle, bam_mux_rx_q_size,
 			gbam_epout_complete, GFP_ATOMIC);
 	if (ret) {
 		pr_err("%s: rx req allocation failed\n", __func__);
@@ -481,7 +487,7 @@
 	}
 
 	ep = port->port_usb->in;
-	ret = gbam_alloc_requests(ep, &d->tx_idle, tx_q_size,
+	ret = gbam_alloc_requests(ep, &d->tx_idle, bam_mux_tx_q_size,
 			gbam_epin_complete, GFP_ATOMIC);
 	if (ret) {
 		pr_err("%s: tx req allocation failed\n", __func__);
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index 093a170..350f286 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -65,9 +65,10 @@
 
 #define ULPI_IO_TIMEOUT_USEC	(10 * 1000)
 
-#define USB_PHY_VDD_DIG_VOL_MIN	1000000 /* uV */
-#define USB_PHY_VDD_DIG_VOL_MAX	1320000 /* uV */
-#define USB_PHY_VDD_DIG_LOAD	49360	/* uA */
+#define USB_PHY_VDD_DIG_VOL_SUSP_MIN	500000 /* uV */
+#define USB_PHY_VDD_DIG_VOL_MIN		1000000 /* uV */
+#define USB_PHY_VDD_DIG_VOL_MAX		1320000 /* uV */
+#define USB_PHY_VDD_DIG_LOAD		49360	/* uA */
 
 static int msm_hsic_init_vddcx(struct msm_hsic_hcd *mehci, int init)
 {
@@ -431,6 +432,12 @@
 				"TCXO D1 buffer%d\n", __func__, ret);
 	}
 
+	ret = regulator_set_voltage(mehci->hsic_vddcx,
+				USB_PHY_VDD_DIG_VOL_SUSP_MIN,
+				USB_PHY_VDD_DIG_VOL_MAX);
+	if (ret < 0)
+		dev_err(mehci->dev, "unable to set vddcx voltage: min:0.5v max:1.3v\n");
+
 	atomic_set(&mehci->in_lpm, 1);
 	enable_irq(hcd->irq);
 	wake_unlock(&mehci->wlock);
@@ -454,6 +461,12 @@
 
 	wake_lock(&mehci->wlock);
 
+	ret = regulator_set_voltage(mehci->hsic_vddcx,
+				USB_PHY_VDD_DIG_VOL_MIN,
+				USB_PHY_VDD_DIG_VOL_MAX);
+	if (ret < 0)
+		dev_err(mehci->dev, "unable to set vddcx voltage: min:1v max:1.3v\n");
+
 	pdata = mehci->dev->platform_data;
 	if (pdata->hub_reset) {
 		ret = msm_xo_mode_vote(mehci->xo_handle, MSM_XO_MODE_ON);
diff --git a/drivers/usb/otg/msm72k_otg.c b/drivers/usb/otg/msm72k_otg.c
index 84b8472..7067662 100644
--- a/drivers/usb/otg/msm72k_otg.c
+++ b/drivers/usb/otg/msm72k_otg.c
@@ -37,7 +37,13 @@
 #define DRIVER_NAME	"msm_otg"
 static void otg_reset(struct otg_transceiver *xceiv, int phy_reset);
 static void msm_otg_set_vbus_state(int online);
-static void msm_otg_set_id_state(int online);
+#ifdef CONFIG_USB_EHCI_MSM_72K
+static void msm_otg_set_id_state(int id);
+#else
+static void msm_otg_set_id_state(int id)
+{
+}
+#endif
 
 struct msm_otg *the_msm_otg;
 
@@ -45,9 +51,7 @@
 {
 	struct msm_otg *dev = the_msm_otg;
 
-	if (dev->pmic_id_notif_supp)
-		return dev->pmic_id_status ? 0 : 1;
-	else if (dev->pdata->otg_mode == OTG_ID)
+	if (dev->pdata->otg_mode == OTG_ID)
 		return (OTGSC_ID & readl(USB_OTGSC)) ? 0 : 1;
 	else
 		return !test_bit(ID, &dev->inputs);
@@ -135,24 +139,38 @@
 #ifdef CONFIG_USB_EHCI_MSM_72K
 static void enable_idgnd(struct msm_otg *dev)
 {
+	unsigned temp;
+
 	/* Do nothing if instead of ID pin, USER controls mode switch */
 	if (dev->pdata->otg_mode == OTG_USER_CONTROL)
 		return;
 
 	ulpi_write(dev, (1<<4), 0x0E);
 	ulpi_write(dev, (1<<4), 0x11);
-	writel(readl(USB_OTGSC) | OTGSC_IDIE, USB_OTGSC);
+	ulpi_write(dev, (1<<0), 0x0B);
+	temp = OTGSC_IDIE | OTGSC_IDPU;
+	writel_relaxed(readl_relaxed(USB_OTGSC) | temp, USB_OTGSC);
 }
 
 static void disable_idgnd(struct msm_otg *dev)
 {
+	unsigned temp;
+
 	/* Do nothing if instead of ID pin, USER controls mode switch */
 	if (dev->pdata->otg_mode == OTG_USER_CONTROL)
 		return;
-
+	temp = OTGSC_IDIE | OTGSC_IDPU;
+	writel_relaxed(readl_relaxed(USB_OTGSC) & ~temp, USB_OTGSC);
 	ulpi_write(dev, (1<<4), 0x0F);
 	ulpi_write(dev, (1<<4), 0x12);
-	writel(readl(USB_OTGSC) & ~OTGSC_IDIE, USB_OTGSC);
+	ulpi_write(dev, (1<<0), 0x0C);
+}
+#else
+static void enable_idgnd(struct msm_otg *dev)
+{
+}
+static void disable_idgnd(struct msm_otg *dev)
+{
 }
 #endif
 
@@ -224,6 +242,9 @@
 #define get_aca_bmaxpower(dev)		(dev->b_max_power)
 #define set_aca_bmaxpower(dev, power)	(dev->b_max_power = power)
 #else
+static void set_aca_id_inputs(struct msm_otg *dev)
+{
+}
 #define get_aca_bmaxpower(dev)		0
 #define set_aca_bmaxpower(dev, power)
 #endif
@@ -692,6 +713,31 @@
 	 * 4. peripheral is supported, but, vbus is not routed to pmic
 	 */
 	host_bus_suspend = dev->otg.host && is_host();
+
+	/*
+	 *  Configure the PMIC ID only in case of cable disconnect.
+	 *  PMIC doesn't generate interrupt for ID_GND to ID_A
+	 *  transistion. hence use the PHY ID cricuit.
+	 */
+	if (dev->pdata->pmic_id_notif_init && !host_bus_suspend &&
+		!test_bit(ID_A, &dev->inputs)) {
+		disable_idgnd(dev);
+		ret = dev->pdata->pmic_id_notif_init(
+			&msm_otg_set_id_state, 1);
+		if (!ret) {
+			dev->pmic_id_notif_supp = 1;
+			if (dev->pdata->pmic_id_irq)
+				dev->id_irq = dev->pdata->pmic_id_irq;
+		} else if (ret == -ENOTSUPP) {
+			pr_debug("%s:USB ID is not routed to pmic",
+			__func__);
+			enable_idgnd(dev);
+		} else {
+			pr_err("%s: pmic_id_ notif_init failed err:%d",
+				__func__, ret);
+		}
+	}
+
 	if ((dev->otg.gadget && chg_type == USB_CHG_TYPE__WALLCHARGER) ||
 		host_bus_suspend ||
 		(dev->otg.host && !dev->pmic_id_notif_supp) ||
@@ -760,7 +806,8 @@
 	 * that there is no harm with this. Till hw folks confirms this
 	 * put regulators in lpm.
 	 */
-	if (!host_bus_suspend && dev->pmic_vbus_notif_supp) {
+	 if (!host_bus_suspend && dev->pmic_vbus_notif_supp &&
+		!test_bit(ID_A, &dev->inputs)) {
 		pr_debug("phy can power collapse: (%d)\n",
 			can_phy_power_collapse(dev));
 		if (can_phy_power_collapse(dev) && dev->pdata->ldo_enable) {
@@ -881,9 +928,23 @@
 	}
 
 phy_resumed:
+	if (dev->pmic_id_notif_supp) {
+		dev->pdata->pmic_id_notif_init(&msm_otg_set_id_state, 0);
+		dev->pmic_id_notif_supp = 0;
+		enable_idgnd(dev);
+	}
+
 	/* Enable Idabc interrupts as these were disabled before entering LPM */
 	enable_idabc(dev);
 
+	/*
+	 * There is corner case where host won't be resumed
+	 * while transitioning from ID_GND to ID_A. In that
+	 * IDGND might have cleared and ID_A might not have updated
+	 * yet. Hence update the ACA states explicitly.
+	 */
+	set_aca_id_inputs(dev);
+
 	/* If resume signalling finishes before lpm exit, PCD is not set in
 	 * USBSTS register. Drive resume signal to the downstream device now
 	 * so that host driver can process the upcoming port change interrupt.*/
@@ -996,6 +1057,12 @@
 			}
 			udelay(10);
 		}
+		if (dev->pmic_id_notif_supp) {
+			dev->pdata->pmic_id_notif_init(
+				&msm_otg_set_id_state, 0);
+			dev->pmic_id_notif_supp = 0;
+			enable_idgnd(dev);
+		}
 out:
 		enable_idabc(dev);
 		enable_irq(dev->irq);
@@ -1119,23 +1186,20 @@
 #endif
 	return 0;
 }
-#endif
 
-void msm_otg_set_id_state(int id)
+static void msm_otg_set_id_state(int id)
 {
 	struct msm_otg *dev = the_msm_otg;
 	unsigned long flags;
 
-	if (id == dev->pmic_id_status)
+	if (!atomic_read(&dev->in_lpm))
 		return;
 
 	if (id) {
 		set_bit(ID, &dev->inputs);
-		dev->pmic_id_status = 1;
 	} else {
 		clear_bit(ID, &dev->inputs);
 		set_bit(A_BUS_REQ, &dev->inputs);
-		dev->pmic_id_status = 0;
 	}
 	spin_lock_irqsave(&dev->lock, flags);
 	if (dev->otg.state != OTG_STATE_UNDEFINED) {
@@ -1144,6 +1208,7 @@
 	}
 	spin_unlock_irqrestore(&dev->lock, flags);
 }
+#endif
 
 void msm_otg_set_vbus_state(int online)
 {
@@ -1973,6 +2038,7 @@
 		} else if (test_bit(ID_A, &dev->inputs)) {
 			dev->pdata->vbus_power(USB_PHY_INTEGRATED, 0);
 		} else if (!test_bit(ID, &dev->inputs)) {
+			msm_otg_set_power(&dev->otg, 0);
 			dev->pdata->vbus_power(USB_PHY_INTEGRATED, 1);
 		}
 		break;
@@ -2687,12 +2753,10 @@
 		}
 	}
 
-	if (dev->pdata->pmic_id_notif_init) {
-		ret = dev->pdata->pmic_id_notif_init(&msm_otg_set_id_state, 1);
-		if (!ret) {
-			dev->pmic_id_notif_supp = 1;
-		} else if (ret != -ENOTSUPP) {
-			pr_err("%s: pmic_id_ notif_init failed err:%d",
+	if (dev->pdata->phy_id_setup_init) {
+		ret = dev->pdata->phy_id_setup_init(1);
+		if (ret) {
+			pr_err("%s: phy_id_setup_init failed err:%d",
 					__func__, ret);
 			goto free_pmic_vbus_notif;
 		}
@@ -2700,8 +2764,6 @@
 
 	if (dev->pdata->pmic_vbus_irq)
 		dev->vbus_on_irq = dev->pdata->pmic_vbus_irq;
-	if (dev->pdata->pmic_id_irq)
-		dev->id_irq = dev->pdata->pmic_id_irq;
 
 	/* vote for vddcx, as PHY cannot tolerate vddcx below 1.0V */
 	if (dev->pdata->init_vddcx) {
@@ -2709,7 +2771,7 @@
 		if (ret) {
 			pr_err("%s: unable to enable vddcx digital core:%d\n",
 				__func__, ret);
-			goto free_pmic_id_notif;
+			goto free_phy_id_setup;
 		}
 	}
 
@@ -2819,9 +2881,9 @@
 free_config_vddcx:
 	if (dev->pdata->init_vddcx)
 		dev->pdata->init_vddcx(0);
-free_pmic_id_notif:
-	if (dev->pdata->pmic_id_notif_init && dev->pmic_id_notif_supp)
-		dev->pdata->pmic_id_notif_init(&msm_otg_set_id_state, 0);
+free_phy_id_setup:
+	if (dev->pdata->phy_id_setup_init)
+		dev->pdata->phy_id_setup_init(0);
 free_pmic_vbus_notif:
 	if (dev->pdata->pmic_vbus_notif_init && dev->pmic_vbus_notif_supp)
 		dev->pdata->pmic_vbus_notif_init(&msm_otg_set_vbus_state, 0);
@@ -2890,6 +2952,9 @@
 	if (dev->pmic_vbus_notif_supp)
 		dev->pdata->pmic_vbus_notif_init(&msm_otg_set_vbus_state, 0);
 
+	if (dev->pdata->phy_id_setup_init)
+		dev->pdata->phy_id_setup_init(0);
+
 	if (dev->pmic_id_notif_supp)
 		dev->pdata->pmic_id_notif_init(&msm_otg_set_id_state, 0);
 
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 6c60cc9..7a9f86b 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -291,6 +291,34 @@
 	return ret < 0 ? ret : 0;
 }
 
+static void msm_hsusb_mhl_switch_enable(struct msm_otg *motg, bool on)
+{
+	static struct regulator *mhl_analog_switch;
+	struct msm_otg_platform_data *pdata = motg->pdata;
+
+	if (!pdata->mhl_enable)
+		return;
+
+	if (on) {
+		mhl_analog_switch = regulator_get(motg->otg.dev,
+					       "mhl_ext_3p3v");
+		if (IS_ERR(mhl_analog_switch)) {
+			pr_err("Unable to get mhl_analog_switch\n");
+			return;
+		}
+
+		if (regulator_enable(mhl_analog_switch)) {
+			pr_err("unable to enable mhl_analog_switch\n");
+			goto put_analog_switch;
+		}
+		return;
+	}
+
+	regulator_disable(mhl_analog_switch);
+put_analog_switch:
+	regulator_put(mhl_analog_switch);
+}
+
 static int ulpi_read(struct otg_transceiver *otg, u32 reg)
 {
 	struct msm_otg *motg = container_of(otg, struct msm_otg, otg);
@@ -600,6 +628,9 @@
 	if (motg->core_clk)
 		clk_disable(motg->core_clk);
 
+	if (!IS_ERR(motg->system_clk))
+		clk_disable(motg->system_clk);
+
 	if (!IS_ERR(motg->pclk_src))
 		clk_disable(motg->pclk_src);
 
@@ -608,8 +639,10 @@
 		motg->lpm_flags |= PHY_PWR_COLLAPSED;
 	}
 
-	if (motg->lpm_flags & PHY_RETENTIONED)
+	if (motg->lpm_flags & PHY_RETENTIONED) {
 		msm_hsusb_config_vddcx(0);
+		msm_hsusb_mhl_switch_enable(motg, 0);
+	}
 
 	if (device_may_wakeup(otg->dev)) {
 		enable_irq_wake(motg->irq);
@@ -642,6 +675,9 @@
 	if (!IS_ERR(motg->pclk_src))
 		clk_enable(motg->pclk_src);
 
+	if (!IS_ERR(motg->system_clk))
+		clk_enable(motg->system_clk);
+
 	clk_enable(motg->pclk);
 	if (motg->core_clk)
 		clk_enable(motg->core_clk);
@@ -652,6 +688,7 @@
 	}
 
 	if (motg->lpm_flags & PHY_RETENTIONED) {
+		msm_hsusb_mhl_switch_enable(motg, 1);
 		msm_hsusb_config_vddcx(1);
 		writel_relaxed(readl_relaxed(USB_PHY_CTRL) | PHY_RETEN,
 				USB_PHY_CTRL);
@@ -1963,6 +2000,8 @@
 		}
 	}
 
+	msm_hsusb_mhl_switch_enable(motg, 1);
+
 	platform_set_drvdata(pdev, motg);
 	device_init_wakeup(&pdev->dev, 1);
 	motg->mA_port = IUNIT;
@@ -2046,6 +2085,7 @@
 	pm_runtime_disable(&pdev->dev);
 	wake_lock_destroy(&motg->wlock);
 
+	msm_hsusb_mhl_switch_enable(motg, 0);
 	if (motg->pdata->pmic_id_irq)
 		free_irq(motg->pdata->pmic_id_irq, motg);
 	otg_set_transceiver(NULL);
@@ -2070,6 +2110,8 @@
 	clk_disable(motg->pclk);
 	if (motg->core_clk)
 		clk_disable(motg->core_clk);
+	if (!IS_ERR(motg->system_clk))
+		clk_disable(motg->system_clk);
 	if (!IS_ERR(motg->pclk_src)) {
 		clk_disable(motg->pclk_src);
 		clk_put(motg->pclk_src);
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index 9805b6c..4b34969 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -3088,10 +3088,36 @@
 
 	HDMI_OUTP(HDMI_AUDIO_CFG, hdmi_audio_config);
 
+	mb();
+	pr_info("%s :HDMI_AUDIO_CFG 0x%08x\n", __func__,
+		HDMI_INP(HDMI_AUDIO_CFG));
+
 	return 0;
 }
 EXPORT_SYMBOL(hdmi_audio_enable);
 
+#define HDMI_AUDIO_PKT_CTRL			0x0020
+#define HDMI_AUDIO_SAMPLE_SEND_ENABLE		1
+
+int hdmi_audio_packet_enable(bool on)
+{
+	u32 hdmi_audio_pkt_ctrl;
+	hdmi_audio_pkt_ctrl = HDMI_INP(HDMI_AUDIO_PKT_CTRL);
+
+	if (on)
+		hdmi_audio_pkt_ctrl |= HDMI_AUDIO_SAMPLE_SEND_ENABLE;
+	else
+		hdmi_audio_pkt_ctrl &= ~(HDMI_AUDIO_SAMPLE_SEND_ENABLE);
+
+	HDMI_OUTP(HDMI_AUDIO_PKT_CTRL, hdmi_audio_pkt_ctrl);
+
+	mb();
+	pr_info("%s : HDMI_AUDIO_PKT_CTRL 0x%08x\n", __func__,
+	HDMI_INP(HDMI_AUDIO_PKT_CTRL));
+	return 0;
+}
+EXPORT_SYMBOL(hdmi_audio_packet_enable);
+
 static void hdmi_msm_audio_info_setup(boolean enabled, int num_of_channels,
 	int level_shift, boolean down_mix)
 {
@@ -3294,7 +3320,8 @@
 		external_common_state->video_resolution,
 		MSM_HDMI_SAMPLE_RATE_48KHZ, channels);
 	hdmi_msm_audio_info_setup(TRUE, channels, 0, FALSE);
-	hdmi_msm_audio_ctrl_setup(TRUE, 1);
+
+	hdmi_msm_audio_ctrl_setup(FALSE, 1);
 
 	/* Turn on Audio FIFO and SAM DROP ISR */
 	HDMI_OUTP(0x02CC, HDMI_INP(0x02CC) | BIT(1) | BIT(3));
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index 5d8c547..d757b5d 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -428,9 +428,7 @@
 	struct mdp4_overlay_pipe *pipe);
 int mdp4_overlay_play_wait(struct fb_info *info,
 	struct msmfb_overlay_data *req);
-int mdp4_overlay_play(struct fb_info *info, struct msmfb_overlay_data *req,
-		struct file **pp_src_file, struct file **pp_src_plane1_file,
-		struct file **pp_src_plane2_file);
+int mdp4_overlay_play(struct fb_info *info, struct msmfb_overlay_data *req);
 struct mdp4_overlay_pipe *mdp4_overlay_pipe_alloc(int ptype, int mixer,
 				int req_share);
 void mdp4_overlay_pipe_free(struct mdp4_overlay_pipe *pipe);
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index 6d63229..dbed160 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -1821,39 +1821,57 @@
 }
 
 static int get_img(struct msmfb_data *img, struct fb_info *info,
-	unsigned long *start, unsigned long *len, struct file **pp_file)
+	unsigned long *start, unsigned long *len, struct file **srcp_file,
+	struct ion_handle **srcp_ihdl)
 {
-	int put_needed, ret = 0, fb_num;
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+#endif
 	struct file *file;
+	int put_needed, ret = 0, fb_num;
 #ifdef CONFIG_ANDROID_PMEM
 	unsigned long vstart;
 #endif
-
 	if (img->flags & MDP_BLIT_SRC_GEM) {
-		*pp_file = NULL;
+		*srcp_file = NULL;
 		return kgsl_gem_obj_addr(img->memory_id, (int) img->priv,
 					 start, len);
 	}
 
-#ifdef CONFIG_ANDROID_PMEM
-	if (!get_pmem_file(img->memory_id, start, &vstart, len, pp_file))
-		return 0;
-#endif
-	file = fget_light(img->memory_id, &put_needed);
-	if (file == NULL)
-		return -1;
+	if (img->flags & MDP_MEMORY_ID_TYPE_FB) {
+		file = fget_light(img->memory_id, &put_needed);
+		if (file == NULL)
+			return -EINVAL;
 
-	if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
-		fb_num = MINOR(file->f_dentry->d_inode->i_rdev);
-		if (get_fb_phys_info(start, len, fb_num))
+		if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
+			fb_num = MINOR(file->f_dentry->d_inode->i_rdev);
+			if (get_fb_phys_info(start, len, fb_num))
+				ret = -1;
+			else
+				*srcp_file = file;
+		} else
 			ret = -1;
-		else
-			*pp_file = file;
-	} else
-		ret = -1;
-	if (ret)
-		fput_light(file, put_needed);
-	return ret;
+		if (ret)
+			fput_light(file, put_needed);
+		return ret;
+	}
+
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	*srcp_ihdl = ion_import_fd(mfd->client, img->memory_id);
+	if (IS_ERR_OR_NULL(*srcp_ihdl))
+		return PTR_ERR(*srcp_ihdl);
+	if (!ion_phys(mfd->client, *srcp_ihdl, start, (size_t *) len))
+		return 0;
+	else
+		return -EINVAL;
+#endif
+#ifdef CONFIG_ANDROID_PMEM
+	if (!get_pmem_file(img->memory_id, start, &vstart,
+					    len, srcp_file))
+		return 0;
+	else
+		return -EINVAL;
+#endif
 }
 
 #ifdef CONFIG_FB_MSM_MIPI_DSI
@@ -2306,9 +2324,7 @@
 	return 0;
 }
 
-int mdp4_overlay_play(struct fb_info *info, struct msmfb_overlay_data *req,
-		struct file **pp_src_file, struct file **pp_src_plane1_file,
-		struct file **pp_src_plane2_file)
+int mdp4_overlay_play(struct fb_info *info, struct msmfb_overlay_data *req)
 {
 	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
 	struct msmfb_data *img;
@@ -2316,9 +2332,12 @@
 	struct mdp4_pipe_desc *pd;
 	ulong start, addr;
 	ulong len = 0;
-	struct file *p_src_file = 0;
-	struct file *p_src_plane1_file = 0, *p_src_plane2_file = 0;
+	struct file *srcp0_file = NULL;
+	struct file *srcp1_file = NULL, *srcp2_file = NULL;
+	struct ion_handle *srcp0_ihdl = NULL;
+	struct ion_handle *srcp1_ihdl = NULL, *srcp2_ihdl = NULL;
 	uint32_t overlay_version = 0;
+	int ret = 0;
 
 	if (mfd == NULL)
 		return -ENODEV;
@@ -2346,13 +2365,13 @@
 	pd->player = pipe;	/* keep */
 
 	img = &req->data;
-	get_img(img, info, &start, &len, &p_src_file);
+	get_img(img, info, &start, &len, &srcp0_file, &srcp0_ihdl);
 	if (len == 0) {
 		mutex_unlock(&mfd->dma->ov_mutex);
 		pr_err("%s: pmem Error\n", __func__);
-		return -1;
+		ret = -1;
+		goto end;
 	}
-	*pp_src_file = p_src_file;
 
 	addr = start + img->offset;
 	pipe->srcp0_addr = addr;
@@ -2364,14 +2383,15 @@
 	if (pipe->fetch_plane == OVERLAY_PLANE_PSEUDO_PLANAR) {
 		if (overlay_version > 0) {
 			img = &req->plane1_data;
-			get_img(img, info, &start, &len, &p_src_plane1_file);
+			get_img(img, info, &start, &len, &srcp1_file,
+				&srcp1_ihdl);
 			if (len == 0) {
 				mutex_unlock(&mfd->dma->ov_mutex);
 				pr_err("%s: Error to get plane1\n", __func__);
-				return -EINVAL;
+				ret = -EINVAL;
+				goto end;
 			}
 			pipe->srcp1_addr = start + img->offset;
-			*pp_src_plane1_file = p_src_plane1_file;
 		} else if (pipe->frame_format ==
 				MDP4_FRAME_FORMAT_VIDEO_SUPERTILE) {
 			struct tile_desc tile;
@@ -2395,24 +2415,26 @@
 	} else if (pipe->fetch_plane == OVERLAY_PLANE_PLANAR) {
 		if (overlay_version > 0) {
 			img = &req->plane1_data;
-			get_img(img, info, &start, &len, &p_src_plane1_file);
+			get_img(img, info, &start, &len, &srcp1_file,
+				&srcp1_ihdl);
 			if (len == 0) {
 				mutex_unlock(&mfd->dma->ov_mutex);
 				pr_err("%s: Error to get plane1\n", __func__);
-				return -EINVAL;
+				ret = -EINVAL;
+				goto end;
 			}
 			pipe->srcp1_addr = start + img->offset;
-			*pp_src_plane1_file = p_src_plane1_file;
 
 			img = &req->plane2_data;
-			get_img(img, info, &start, &len, &p_src_plane2_file);
+			get_img(img, info, &start, &len, &srcp2_file,
+				&srcp2_ihdl);
 			if (len == 0) {
 				mutex_unlock(&mfd->dma->ov_mutex);
 				pr_err("%s: Error to get plane2\n", __func__);
-				return -EINVAL;
+				ret = -EINVAL;
+				goto end;
 			}
 			pipe->srcp2_addr = start + img->offset;
-			*pp_src_plane2_file = p_src_plane2_file;
 		} else {
 			if (pipe->src_format == MDP_Y_CR_CB_GH2V2) {
 				addr += (ALIGN(pipe->src_width, 16) *
@@ -2495,7 +2517,7 @@
 			if (pipe->flags & MDP_OV_PLAY_NOWAIT) {
 				mdp4_stat.overlay_play[pipe->mixer_num]++;
 				mutex_unlock(&mfd->dma->ov_mutex);
-				return 0;
+				goto end;
 			}
 #ifdef CONFIG_FB_MSM_MIPI_DSI
 			if (ctrl->panel_mode & MDP4_PANEL_DSI_CMD) {
@@ -2512,8 +2534,23 @@
 	}
 
 	mdp4_stat.overlay_play[pipe->mixer_num]++;
-
 	mutex_unlock(&mfd->dma->ov_mutex);
-
-	return 0;
+end:
+#ifdef CONFIG_ANDROID_PMEM
+	if (srcp0_file)
+		put_pmem_file(srcp0_file);
+	if (srcp1_file)
+		put_pmem_file(srcp1_file);
+	if (srcp2_file)
+		put_pmem_file(srcp2_file);
+#endif
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	if (!IS_ERR_OR_NULL(srcp0_ihdl))
+		ion_free(mfd->client, srcp0_ihdl);
+	if (!IS_ERR_OR_NULL(srcp1_ihdl))
+		ion_free(mfd->client, srcp1_ihdl);
+	if (!IS_ERR_OR_NULL(srcp2_ihdl))
+		ion_free(mfd->client, srcp2_ihdl);
+#endif
+	return ret;
 }
diff --git a/drivers/video/msm/mdp4_overlay_dsi_video.c b/drivers/video/msm/mdp4_overlay_dsi_video.c
index 5cf79c1..4e47093 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_video.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_video.c
@@ -555,11 +555,11 @@
 void mdp4_overlay0_done_dsi_video(struct mdp_dma_data *dma)
 {
 	spin_lock(&mdp_spin_lock);
+	dma->busy = FALSE;
 	if (dsi_pipe->blt_addr == 0) {
 		spin_unlock(&mdp_spin_lock);
 		return;
 	}
-	dma->busy = FALSE;
 	mdp4_dsi_video_blt_dmap_update(dsi_pipe);
 	dsi_pipe->dmap_cnt++;
 	mdp_disable_irq_nosync(MDP_OVERLAY0_TERM);
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index 0eda69a..75264ef 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -451,11 +451,11 @@
 void mdp4_overlay0_done_lcdc(struct mdp_dma_data *dma)
 {
 	spin_lock(&mdp_spin_lock);
+	dma->busy = FALSE;
 	if (lcdc_pipe->blt_addr == 0) {
 		spin_unlock(&mdp_spin_lock);
 		return;
 	}
-	dma->busy = FALSE;
 	mdp4_lcdc_blt_dmap_update(lcdc_pipe);
 	lcdc_pipe->dmap_cnt++;
 	mdp_disable_irq_nosync(MDP_OVERLAY0_TERM);
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 7595838..10e4156 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -2526,8 +2526,6 @@
 	int	ret;
 	struct msmfb_overlay_data req;
 	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
-	struct file *p_src_file = 0;
-	struct file *p_src_plane1_file = 0, *p_src_plane2_file = 0;
 
 	if (mfd->overlay_play_enable == 0)	/* nothing to do */
 		return 0;
@@ -2549,17 +2547,7 @@
 	add_timer(&mfd->msmfb_no_update_notify_timer);
 	mutex_unlock(&msm_fb_notify_update_sem);
 
-	ret = mdp4_overlay_play(info, &req, &p_src_file, &p_src_plane1_file,
-				&p_src_plane2_file);
-
-#ifdef CONFIG_ANDROID_PMEM
-	if (p_src_file)
-		put_pmem_file(p_src_file);
-	if (p_src_plane1_file)
-		put_pmem_file(p_src_plane1_file);
-	if (p_src_plane2_file)
-		put_pmem_file(p_src_plane2_file);
-#endif
+	ret = mdp4_overlay_play(info, &req);
 
 	return ret;
 }
@@ -3304,7 +3292,9 @@
 	mfd->fb_page = fb_num;
 	mfd->index = fbi_list_index;
 	mfd->mdp_fb_page_protection = MDP_FB_PAGE_PROTECTION_WRITECOMBINE;
-
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	mfd->client = msm_ion_client_create(-1, pdev->name);
+#endif
 	/* link to the latest pdev */
 	mfd->pdev = this_dev;
 
diff --git a/drivers/video/msm/msm_fb.h b/drivers/video/msm/msm_fb.h
index a650e73..bc25062 100644
--- a/drivers/video/msm/msm_fb.h
+++ b/drivers/video/msm/msm_fb.h
@@ -37,6 +37,7 @@
 #include <linux/fb.h>
 #include <linux/list.h>
 #include <linux/types.h>
+#include <linux/ion.h>
 
 #include <linux/msm_mdp.h>
 #ifdef CONFIG_HAS_EARLYSUSPEND
@@ -172,6 +173,7 @@
 	struct list_head writeback_free_queue;
 	struct list_head writeback_register_queue;
 	wait_queue_head_t		wait_q;
+	struct ion_client *client;
 };
 
 struct dentry *msm_fb_get_debugfs_root(void);
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 0405513..a8aa44a 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -329,7 +329,7 @@
 			DDL_CLIENT_WAIT_FOR_INITCODEC) ||
 			DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB) ||
 			DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN))) {
-			phys_addr = mv_buff->physical_addr;
+			phys_addr = mv_buff->dev_addr;
 			virt_addr = mv_buff->kernel_virtual_addr;
 			buffer_size = mv_buff->size/mv_buff->count;
 
@@ -853,7 +853,7 @@
 				vcd_property_enc_recon_buffer)) {
 				encoder->hw_bufs.dpb_y[index_hw_bufs].
 				align_physical_addr =
-					recon_buffers->physical_addr;
+					recon_buffers->dev_addr;
 				encoder->hw_bufs.dpb_y[index_hw_bufs].
 				align_virtual_addr =
 					recon_buffers->kernel_virtual_addr;
@@ -861,7 +861,7 @@
 				buffer_size = recon_buffers->buffer_size;
 				encoder->hw_bufs.dpb_c[index_hw_bufs].
 				align_physical_addr =
-				recon_buffers->physical_addr +
+				recon_buffers->dev_addr +
 					ddl_get_yuv_buf_size(
 						encoder->frame_size.width,
 						encoder->frame_size.height,
diff --git a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c
index bb9b9c1..6343202 100644
--- a/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c
+++ b/drivers/video/msm/vidc/720p/ddl/vcd_ddl_hal.c
@@ -771,6 +771,7 @@
 	struct ddl_decoder_data *decoder = &(ddl->codec_data.decoder);
 	u32 comv_buf_size = DDL_COMV_BUFLINE_NO, comv_buf_no = 0;
 	u32 ref_buf_no = 0;
+	struct ddl_context  *ddl_ctxt = NULL;
 
 	if (!DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_WAIT_FOR_DPB)) {
 		VIDC_LOG_STRING("STATE-CRITICAL");
@@ -857,6 +858,10 @@
 	}
 	ddl_decode_set_metadata_output(decoder);
 	ddl_decoder_dpb_transact(decoder, NULL, DDL_DPB_OP_INIT);
+	ddl_ctxt = ddl_get_context();
+	vidc_720p_set_deblock_line_buffer(
+		ddl_ctxt->db_line_buffer.align_physical_addr,
+		ddl_ctxt->db_line_buffer.buffer_size);
 	ddl_move_client_state(ddl, DDL_CLIENT_WAIT_FOR_DPBDONE);
 	ddl_move_command_state(ddl->ddl_context, DDL_CMD_DECODE_SET_DPB);
 
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
index 9440f15..a5994dc 100644
--- a/drivers/video/msm/vidc/common/dec/vdec.c
+++ b/drivers/video/msm/vidc/common/dec/vdec.c
@@ -28,7 +28,7 @@
 #include <linux/android_pmem.h>
 #include <linux/clk.h>
 #include <linux/timer.h>
-
+#include <mach/msm_subsystem_map.h>
 #include "vidc_type.h"
 #include "vcd_api.h"
 #include "vdec_internal.h"
@@ -50,6 +50,8 @@
 static struct vid_dec_dev *vid_dec_device_p;
 static dev_t vid_dec_dev_num;
 static struct class *vid_dec_class;
+static unsigned int vidc_mmu_subsystem[] = {
+	MSM_SUBSYSTEM_VIDEO};
 static s32 vid_dec_get_empty_client_index(void)
 {
 	u32 i, found = false;
@@ -743,9 +745,10 @@
 					struct vdec_h264_mv *mv_data)
 {
 	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_h264_mv_buffer vcd_h264_mv_buffer;
+	struct vcd_property_h264_mv_buffer *vcd_h264_mv_buffer = NULL;
+	struct msm_mapped_buffer *mapped_buffer = NULL;
 	u32 vcd_status = VCD_ERR_FAIL;
-	u32 len;
+	u32 len = 0, flags = 0;
 	struct file *file;
 
 	if (!client_ctx || !mv_data)
@@ -753,29 +756,41 @@
 
 	vcd_property_hdr.prop_id = VCD_I_H264_MV_BUFFER;
 	vcd_property_hdr.sz = sizeof(struct vcd_property_h264_mv_buffer);
+	vcd_h264_mv_buffer = &client_ctx->vcd_h264_mv_buffer;
 
-	memset(&vcd_h264_mv_buffer, 0,
+	memset(&client_ctx->vcd_h264_mv_buffer, 0,
 		   sizeof(struct vcd_property_h264_mv_buffer));
-	vcd_h264_mv_buffer.size = mv_data->size;
-	vcd_h264_mv_buffer.count = mv_data->count;
-	vcd_h264_mv_buffer.pmem_fd = mv_data->pmem_fd;
-	vcd_h264_mv_buffer.offset = mv_data->offset;
+	vcd_h264_mv_buffer->size = mv_data->size;
+	vcd_h264_mv_buffer->count = mv_data->count;
+	vcd_h264_mv_buffer->pmem_fd = mv_data->pmem_fd;
+	vcd_h264_mv_buffer->offset = mv_data->offset;
 
-	if (get_pmem_file(vcd_h264_mv_buffer.pmem_fd,
-		(unsigned long *) (&(vcd_h264_mv_buffer.physical_addr)),
-		(unsigned long *) (&vcd_h264_mv_buffer.kernel_virtual_addr),
+	if (get_pmem_file(vcd_h264_mv_buffer->pmem_fd,
+		(unsigned long *) (&(vcd_h264_mv_buffer->physical_addr)),
+		(unsigned long *) (&vcd_h264_mv_buffer->kernel_virtual_addr),
 		(unsigned long *) (&len), &file)) {
 		ERR("%s(): get_pmem_file failed\n", __func__);
 		return false;
 	}
 	put_pmem_file(file);
 
-	DBG("Virt: %p, Phys %p, fd: %d\n", vcd_h264_mv_buffer.
-		kernel_virtual_addr, vcd_h264_mv_buffer.physical_addr,
-		vcd_h264_mv_buffer.pmem_fd);
-
+	flags = MSM_SUBSYSTEM_MAP_IOVA;
+	mapped_buffer = msm_subsystem_map_buffer(
+		(unsigned long)vcd_h264_mv_buffer->physical_addr, len,
+			flags, vidc_mmu_subsystem,
+			sizeof(vidc_mmu_subsystem)/sizeof(unsigned int));
+	if (IS_ERR(mapped_buffer)) {
+		pr_err("buffer map failed");
+		return false;
+	}
+	vcd_h264_mv_buffer->client_data = (void *) mapped_buffer;
+	vcd_h264_mv_buffer->dev_addr = (u8 *)mapped_buffer->iova[0];
+	DBG("Virt: %p, Phys %p, fd: %d", vcd_h264_mv_buffer->
+		kernel_virtual_addr, vcd_h264_mv_buffer->physical_addr,
+		vcd_h264_mv_buffer->pmem_fd);
+	DBG("Dev addr %p", vcd_h264_mv_buffer->dev_addr);
 	vcd_status = vcd_set_property(client_ctx->vcd_handle,
-				      &vcd_property_hdr, &vcd_h264_mv_buffer);
+				      &vcd_property_hdr, vcd_h264_mv_buffer);
 
 	if (vcd_status)
 		return false;
@@ -837,6 +852,9 @@
 
 	if (!client_ctx)
 		return false;
+	if (client_ctx->vcd_h264_mv_buffer.client_data)
+		msm_subsystem_unmap_buffer((struct msm_mapped_buffer *)
+		client_ctx->vcd_h264_mv_buffer.client_data);
 
 	vcd_property_hdr.prop_id = VCD_I_FREE_H264_MV_BUFFER;
 	vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size);
@@ -888,7 +906,7 @@
 	enum vcd_buffer_type buffer = VCD_BUFFER_INPUT;
 	enum buffer_dir dir_buffer = BUFFER_TYPE_INPUT;
 	u32 vcd_status = VCD_ERR_FAIL;
-	unsigned long kernel_vaddr, buf_adr_offset = 0;
+	unsigned long kernel_vaddr, buf_adr_offset = 0, length;
 
 	if (!client_ctx || !buffer_info)
 		return false;
@@ -898,12 +916,12 @@
 		buffer = VCD_BUFFER_OUTPUT;
 		buf_adr_offset = (unsigned long)buffer_info->buffer.offset;
 	}
-
+	length = buffer_info->buffer.buffer_len;
 	/*If buffer cannot be set, ignore */
 	if (!vidc_insert_addr_table(client_ctx, dir_buffer,
 		(unsigned long)buffer_info->buffer.bufferaddr,
 		&kernel_vaddr, buffer_info->buffer.pmem_fd,
-		buf_adr_offset, MAX_VIDEO_NUM_OF_BUFF)) {
+		buf_adr_offset, MAX_VIDEO_NUM_OF_BUFF, length)) {
 		DBG("%s() : user_virt_addr = %p cannot be set.",
 		    __func__, buffer_info->buffer.bufferaddr);
 		return false;
diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
index 0d8fcc2..125355e 100644
--- a/drivers/video/msm/vidc/common/enc/venc.c
+++ b/drivers/video/msm/vidc/common/enc/venc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, 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
@@ -966,8 +966,15 @@
 	}
 	case VEN_IOCTL_FREE_RECON_BUFFER:
 	{
+		struct venc_recon_addr venc_recon;
 		DBG("VEN_IOCTL_FREE_RECON_BUFFER\n");
-		result = vid_enc_free_recon_buffers(client_ctx);
+		if (copy_from_user(&venc_msg, arg, sizeof(venc_msg)))
+			return -EFAULT;
+		if (copy_from_user(&venc_recon, venc_msg.in,
+				sizeof(venc_recon)))
+				return -EFAULT;
+		result = vid_enc_free_recon_buffers(client_ctx,
+				&venc_recon);
 		if (!result) {
 			ERR("VEN_IOCTL_FREE_RECON_BUFFER failed\n");
 			return -EIO;
diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.c b/drivers/video/msm/vidc/common/enc/venc_internal.c
index d202d81..c3f0219 100644
--- a/drivers/video/msm/vidc/common/enc/venc_internal.c
+++ b/drivers/video/msm/vidc/common/enc/venc_internal.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, 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
@@ -27,7 +27,7 @@
 #include <linux/workqueue.h>
 #include <linux/android_pmem.h>
 #include <linux/clk.h>
-
+#include <mach/msm_subsystem_map.h>
 #include "vidc_type.h"
 #include "vcd_api.h"
 #include "venc_internal.h"
@@ -40,6 +40,9 @@
 #endif
 
 #define ERR(x...) printk(KERN_ERR x)
+static unsigned int vidc_mmu_subsystem[] = {
+	MSM_SUBSYSTEM_VIDEO};
+
 
 u32 vid_enc_set_get_base_cfg(struct video_client_ctx *client_ctx,
 		struct venc_basecfg *base_config, u32 set_flag)
@@ -1530,7 +1533,7 @@
 	enum vcd_buffer_type vcd_buffer_t = VCD_BUFFER_INPUT;
 	enum buffer_dir dir_buffer = BUFFER_TYPE_INPUT;
 	u32 vcd_status = VCD_ERR_FAIL;
-	unsigned long kernel_vaddr;
+	unsigned long kernel_vaddr, length = 0;
 
 	if (!client_ctx || !buffer_info)
 		return false;
@@ -1539,14 +1542,14 @@
 		dir_buffer = BUFFER_TYPE_OUTPUT;
 		vcd_buffer_t = VCD_BUFFER_OUTPUT;
 	}
-
+	length = buffer_info->sz;
 	/*If buffer cannot be set, ignore */
 	if (!vidc_insert_addr_table(client_ctx, dir_buffer,
 					(unsigned long)buffer_info->pbuffer,
 					&kernel_vaddr,
 					buffer_info->fd,
 					(unsigned long)buffer_info->offset,
-					VID_ENC_MAX_NUM_OF_BUFF)) {
+					VID_ENC_MAX_NUM_OF_BUFF, length)) {
 		DBG("%s() : user_virt_addr = %p cannot be set.",
 		    __func__, buffer_info->pbuffer);
 		return false;
@@ -1697,34 +1700,58 @@
 		struct venc_recon_addr *venc_recon)
 {
 	u32 vcd_status = VCD_ERR_FAIL;
-	u32 len;
+	u32 len, i, flags = 0;
 	struct file *file;
 	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_enc_recon_buffer control;
-
-	control.buffer_size = venc_recon->buffer_size;
-	control.kernel_virtual_addr = NULL;
-	control.physical_addr = NULL;
-	control.pmem_fd = venc_recon->pmem_fd;
-	control.offset = venc_recon->offset;
-
-	if (get_pmem_file(control.pmem_fd, (unsigned long *)
-		(&(control.physical_addr)), (unsigned long *)
-		(&control.kernel_virtual_addr),
+	struct vcd_property_enc_recon_buffer *control = NULL;
+	struct msm_mapped_buffer *mapped_buffer = NULL;
+	if (!client_ctx || !venc_recon) {
+		pr_err("%s() Invalid params", __func__);
+		return false;
+	}
+	len = sizeof(client_ctx->recon_buffer)/
+		sizeof(struct vcd_property_enc_recon_buffer);
+	for (i = 0; i < len; i++) {
+		if (!client_ctx->recon_buffer[i].kernel_virtual_addr) {
+			control = &client_ctx->recon_buffer[i];
+			break;
+		}
+	}
+	if (!control) {
+		pr_err("Exceeded max recon buffer setting");
+		return false;
+	}
+	control->buffer_size = venc_recon->buffer_size;
+	control->kernel_virtual_addr = NULL;
+	control->physical_addr = NULL;
+	control->pmem_fd = venc_recon->pmem_fd;
+	control->offset = venc_recon->offset;
+	control->user_virtual_addr = venc_recon->pbuffer;
+	if (get_pmem_file(control->pmem_fd, (unsigned long *)
+		(&(control->physical_addr)), (unsigned long *)
+		(&control->kernel_virtual_addr),
 		(unsigned long *) (&len), &file)) {
 			ERR("%s(): get_pmem_file failed\n", __func__);
 			return false;
 		}
 		put_pmem_file(file);
-		DBG("Virt: %p, Phys %p, fd: %d", control.kernel_virtual_addr,
-			control.physical_addr, control.pmem_fd);
-
+		flags = MSM_SUBSYSTEM_MAP_IOVA;
+		mapped_buffer = msm_subsystem_map_buffer(
+		(unsigned long)control->physical_addr, len,
+		flags, vidc_mmu_subsystem,
+		sizeof(vidc_mmu_subsystem)/sizeof(unsigned int));
+		if (IS_ERR(mapped_buffer)) {
+			pr_err("buffer map failed");
+			return false;
+		}
+		control->client_data = (void *) mapped_buffer;
+		control->dev_addr = (u8 *)mapped_buffer->iova[0];
 		vcd_property_hdr.prop_id = VCD_I_RECON_BUFFERS;
 		vcd_property_hdr.sz =
 			sizeof(struct vcd_property_enc_recon_buffer);
 
 		vcd_status = vcd_set_property(client_ctx->vcd_handle,
-						&vcd_property_hdr, &control);
+						&vcd_property_hdr, control);
 		if (!vcd_status) {
 			DBG("vcd_set_property returned success\n");
 			return true;
@@ -1735,17 +1762,43 @@
 		}
 }
 
-u32 vid_enc_free_recon_buffers(struct video_client_ctx *client_ctx)
+u32 vid_enc_free_recon_buffers(struct video_client_ctx *client_ctx,
+			struct venc_recon_addr *venc_recon)
 {
 	u32 vcd_status = VCD_ERR_FAIL;
 	struct vcd_property_hdr vcd_property_hdr;
-	struct vcd_property_enc_recon_buffer control;
+	struct vcd_property_enc_recon_buffer *control = NULL;
+	u32 len = 0, i;
+
+	if (!client_ctx || !venc_recon) {
+		pr_err("%s() Invalid params", __func__);
+		return false;
+	}
+	len = sizeof(client_ctx->recon_buffer)/
+		sizeof(struct vcd_property_enc_recon_buffer);
+	pr_err(" %s() address  %p", __func__,
+	venc_recon->pbuffer);
+	for (i = 0; i < len; i++) {
+		if (client_ctx->recon_buffer[i].user_virtual_addr
+			== venc_recon->pbuffer) {
+			control = &client_ctx->recon_buffer[i];
+			break;
+		}
+	}
+	if (!control) {
+		pr_err(" %s() address not found %p", __func__,
+			venc_recon->pbuffer);
+		return false;
+	}
+	if (control->client_data)
+		msm_subsystem_unmap_buffer((struct msm_mapped_buffer *)
+		control->client_data);
 
 	vcd_property_hdr.prop_id = VCD_I_FREE_RECON_BUFFERS;
 	vcd_property_hdr.sz = sizeof(struct vcd_property_buffer_size);
-
 	vcd_status = vcd_set_property(client_ctx->vcd_handle,
-						&vcd_property_hdr, &control);
+						&vcd_property_hdr, control);
+	memset(control, 0, sizeof(struct vcd_property_enc_recon_buffer));
 	return true;
 }
 
diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.h b/drivers/video/msm/vidc/common/enc/venc_internal.h
index 7d4ebca..2b5a532 100644
--- a/drivers/video/msm/vidc/common/enc/venc_internal.h
+++ b/drivers/video/msm/vidc/common/enc/venc_internal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, 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
@@ -143,7 +143,8 @@
 u32 vid_enc_set_recon_buffers(struct video_client_ctx *client_ctx,
 		struct venc_recon_addr *venc_recon);
 
-u32 vid_enc_free_recon_buffers(struct video_client_ctx *client_ctx);
+u32 vid_enc_free_recon_buffers(struct video_client_ctx *client_ctx,
+		struct venc_recon_addr *venc_recon);
 
 u32 vid_enc_get_recon_buffer_size(struct video_client_ctx *client_ctx,
 		struct venc_recon_buff_size *venc_recon_size);
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.c b/drivers/video/msm/vidc/common/init/vidc_init.c
index cda3a91..902a9aa 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init.c
+++ b/drivers/video/msm/vidc/common/init/vidc_init.c
@@ -30,7 +30,7 @@
 #include <linux/debugfs.h>
 #include <mach/clk.h>
 #include <linux/pm_runtime.h>
-
+#include <mach/msm_subsystem_map.h>
 #include "vcd_api.h"
 #include "vidc_init_internal.h"
 #include "vidc_init.h"
@@ -49,6 +49,7 @@
 static struct vidc_dev *vidc_device_p;
 static dev_t vidc_dev_num;
 static struct class *vidc_class;
+static unsigned int vidc_mmu_subsystem[] = {MSM_SUBSYSTEM_VIDEO};
 
 static const struct file_operations vidc_fops = {
 	.owner = THIS_MODULE,
@@ -78,7 +79,7 @@
 				u32 *var)
 {
 	struct dentry *vidc_debugfs_file =
-	    debugfs_create_u32(name, S_IRUGO | S_IWUSR, root, var);
+		debugfs_create_u32(name, S_IRUGO | S_IWUSR, root, var);
 	if (!vidc_debugfs_file)
 		ERR("%s(): Error creating/opening file %s\n", __func__, name);
 }
@@ -413,7 +414,7 @@
 	}
 
 	if (found) {
-		*phy_addr = buf_addr_table[i].phy_addr;
+		*phy_addr = buf_addr_table[i].dev_addr;
 		*pmem_fd = buf_addr_table[i].pmem_fd;
 		*file = buf_addr_table[i].file;
 		*buffer_index = i;
@@ -445,15 +446,17 @@
 u32 vidc_insert_addr_table(struct video_client_ctx *client_ctx,
 	enum buffer_dir buffer, unsigned long user_vaddr,
 	unsigned long *kernel_vaddr, int pmem_fd,
-	unsigned long buffer_addr_offset, unsigned int max_num_buffers)
+	unsigned long buffer_addr_offset, unsigned int max_num_buffers,
+	unsigned long length)
 {
 	unsigned long len, phys_addr;
 	struct file *file;
 	u32 *num_of_buffers = NULL;
-	u32 i;
+	u32 i, flags;
 	struct buf_addr_table *buf_addr_table;
+	struct msm_mapped_buffer *mapped_buffer = NULL;
 
-	if (!client_ctx)
+	if (!client_ctx || !length)
 		return false;
 
 	if (buffer == BUFFER_TYPE_INPUT) {
@@ -493,6 +496,18 @@
 		put_pmem_file(file);
 		phys_addr += buffer_addr_offset;
 		(*kernel_vaddr) += buffer_addr_offset;
+		flags = MSM_SUBSYSTEM_MAP_IOVA;
+		mapped_buffer = msm_subsystem_map_buffer(phys_addr, length,
+		flags, vidc_mmu_subsystem,
+		sizeof(vidc_mmu_subsystem)/sizeof(unsigned int));
+		if (IS_ERR(mapped_buffer)) {
+			pr_err("buffer map failed");
+			return false;
+		}
+		buf_addr_table[*num_of_buffers].client_data = (void *)
+			mapped_buffer;
+		buf_addr_table[*num_of_buffers].dev_addr =
+			mapped_buffer->iova[0];
 		buf_addr_table[*num_of_buffers].user_vaddr = user_vaddr;
 		buf_addr_table[*num_of_buffers].kernel_vaddr = *kernel_vaddr;
 		buf_addr_table[*num_of_buffers].pmem_fd = pmem_fd;
@@ -500,7 +515,7 @@
 		buf_addr_table[*num_of_buffers].phy_addr = phys_addr;
 		*num_of_buffers = *num_of_buffers + 1;
 		DBG("%s() : client_ctx = %p, user_virt_addr = 0x%08lx, "
-			"kernel_vaddr = 0x%08lx inserted!",	__func__,
+			"kernel_vaddr = 0x%08lx inserted!", __func__,
 			client_ctx, user_vaddr, *kernel_vaddr);
 	}
 	return true;
@@ -522,12 +537,10 @@
 	if (buffer == BUFFER_TYPE_INPUT) {
 		buf_addr_table = client_ctx->input_buf_addr_table;
 		num_of_buffers = &client_ctx->num_of_input_buffers;
-		DBG("%s(): buffer = INPUT\n", __func__);
 
 	} else {
 		buf_addr_table = client_ctx->output_buf_addr_table;
 		num_of_buffers = &client_ctx->num_of_output_buffers;
-		DBG("%s(): buffer = OUTPUT\n", __func__);
 	}
 
 	if (!*num_of_buffers)
@@ -538,13 +551,19 @@
 		user_vaddr != buf_addr_table[i].user_vaddr)
 		i++;
 	if (i == *num_of_buffers) {
-		DBG("%s() : client_ctx = %p."
+		pr_err("%s() : client_ctx = %p."
 			" user_virt_addr = 0x%08lx NOT found",
 			__func__, client_ctx, user_vaddr);
 		return false;
 	}
+	msm_subsystem_unmap_buffer(
+	(struct msm_mapped_buffer *)buf_addr_table[i].client_data);
 	*kernel_vaddr = buf_addr_table[i].kernel_vaddr;
 	if (i < (*num_of_buffers - 1)) {
+		buf_addr_table[i].client_data =
+			buf_addr_table[*num_of_buffers - 1].client_data;
+		buf_addr_table[i].dev_addr =
+			buf_addr_table[*num_of_buffers - 1].dev_addr;
 		buf_addr_table[i].user_vaddr =
 			buf_addr_table[*num_of_buffers - 1].user_vaddr;
 		buf_addr_table[i].kernel_vaddr =
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.h b/drivers/video/msm/vidc/common/init/vidc_init.h
index c472718..fecbf59 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init.h
+++ b/drivers/video/msm/vidc/common/init/vidc_init.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2011, 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
@@ -30,6 +30,8 @@
 	unsigned long phy_addr;
 	int pmem_fd;
 	struct file *file;
+	unsigned long dev_addr;
+	void *client_data;
 };
 
 struct video_client_ctx {
@@ -42,6 +44,8 @@
 	struct mutex msg_queue_lock;
 	wait_queue_head_t msg_wait;
 	struct completion event;
+	struct vcd_property_h264_mv_buffer vcd_h264_mv_buffer;
+	struct vcd_property_enc_recon_buffer recon_buffer[4];
 	u32 event_status;
 	u32 seq_header_set;
 	u32 stop_msg;
@@ -61,7 +65,7 @@
 	enum buffer_dir buffer, unsigned long user_vaddr,
 	unsigned long *kernel_vaddr, int pmem_fd,
 	unsigned long buffer_addr_offset,
-	unsigned int max_num_buffers);
+	unsigned int max_num_buffers, unsigned long length);
 u32 vidc_delete_addr_table(struct video_client_ctx *client_ctx,
 	enum buffer_dir buffer, unsigned long user_vaddr,
 	unsigned long *kernel_vaddr);
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_property.h b/drivers/video/msm/vidc/common/vcd/vcd_property.h
index 2cb894e..f51d226 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_property.h
+++ b/drivers/video/msm/vidc/common/vcd/vcd_property.h
@@ -315,12 +315,15 @@
 };
 
 struct vcd_property_enc_recon_buffer{
+	u8 *user_virtual_addr;
 	u8 *kernel_virtual_addr;
 	u8 *physical_addr;
+	u8 *dev_addr;
 	u32 buffer_size;
 	u32 ysize;
 	int pmem_fd;
 	u32 offset;
+	void *client_data;
 };
 
 struct vcd_property_h264_mv_buffer{
@@ -330,6 +333,8 @@
 	u32 count;
 	int pmem_fd;
 	u32 offset;
+	u8 *dev_addr;
+	void *client_data;
 };
 
 struct vcd_property_buffer_size{
diff --git a/include/linux/ion.h b/include/linux/ion.h
index 4b7b8b7d1..7de40d4 100644
--- a/include/linux/ion.h
+++ b/include/linux/ion.h
@@ -113,13 +113,21 @@
 
 /**
  * struct ion_platform_data - array of platform heaps passed from board file
- * @nr:		number of structures in the array
- * @heaps:	array of platform_heap structions
+ * @nr:    number of structures in the array
+ * @request_region: function to be called when the number of allocations goes
+ *						from 0 -> 1
+ * @release_region: function to be called when the number of allocations goes
+ *						from 1 -> 0
+ * @setup_region:   function to be called upon ion registration
+ * @heaps: array of platform_heap structions
  *
  * Provided by the board file in the form of platform data to a platform device.
  */
 struct ion_platform_data {
 	int nr;
+	void (*request_region)(void *);
+	void (*release_region)(void *);
+	void *(*setup_region)(void);
 	struct ion_platform_heap heaps[];
 };
 
diff --git a/include/linux/msm_adc.h b/include/linux/msm_adc.h
index 9818cf0..5d5fb1b 100644
--- a/include/linux/msm_adc.h
+++ b/include/linux/msm_adc.h
@@ -343,7 +343,6 @@
 int32_t adc_channel_close(void *h);
 int32_t adc_channel_request_conv(void *h, struct completion *conv_complete_evt);
 int32_t adc_channel_read_result(void *h, struct adc_chan_result *chan_result);
-int32_t adc_calib_request(void *h, struct completion *calib_complete_evt);
 #else
 int32_t adc_channel_open(uint32_t channel, void **h)
 {
@@ -365,11 +364,6 @@
 	pr_err("%s.not supported.\n", __func__);
 	return -ENODEV;
 }
-int32_t adc_calib_request(void *h, struct completion *calib_complete_evt)
-{
-	pr_err("%s.not supported.\n", __func__);
-	return -ENODEV;
-}
 #endif /* CONFIG_SENSORS_MSM_ADC */
 #endif
 #endif /* __MSM_ADC_H */
diff --git a/include/linux/msm_audio_mvs.h b/include/linux/msm_audio_mvs.h
index 37a6ee7..c934aee 100644
--- a/include/linux/msm_audio_mvs.h
+++ b/include/linux/msm_audio_mvs.h
@@ -94,14 +94,30 @@
 	MVS_G729A_ERASURE
 };
 
+struct min_max_rate {
+	uint32_t min_rate;
+	uint32_t max_rate;
+};
+
 struct msm_audio_mvs_config {
 	uint32_t mvs_mode;
 	uint32_t rate_type;
+	struct min_max_rate min_max_rate;
 	uint32_t dtx_mode;
 };
 
 #define MVS_MAX_VOC_PKT_SIZE 640
 
+struct q6_msm_audio_mvs_frame {
+	union {
+	uint32_t frame_type;
+	uint32_t packet_rate;
+	} header;
+	uint32_t len;
+	uint8_t voc_pkt[MVS_MAX_VOC_PKT_SIZE];
+
+};
+
 struct msm_audio_mvs_frame {
 	uint32_t frame_type;
 	uint32_t len;
diff --git a/include/linux/msm_kgsl.h b/include/linux/msm_kgsl.h
index 84e8564..9db6bc6 100644
--- a/include/linux/msm_kgsl.h
+++ b/include/linux/msm_kgsl.h
@@ -111,6 +111,7 @@
 struct kgsl_pwrlevel {
 	unsigned int gpu_freq;
 	unsigned int bus_freq;
+	unsigned int io_fraction;
 };
 
 struct kgsl_version {
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index d909c8b..5011229 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -131,6 +131,7 @@
 #define MDP_DEINTERLACE_ODD		0x00400000
 #define MDP_OV_PLAY_NOWAIT		0x00200000
 #define MDP_SOURCE_ROTATED_90		0x00100000
+#define MDP_MEMORY_ID_TYPE_FB		0x00001000
 
 #define MDP_TRANSP_NOP 0xffffffff
 #define MDP_ALPHA_NOP 0xff
diff --git a/include/linux/pmic8058-xoadc.h b/include/linux/pmic8058-xoadc.h
index 8a5820f..f72ad66 100644
--- a/include/linux/pmic8058-xoadc.h
+++ b/include/linux/pmic8058-xoadc.h
@@ -65,20 +65,57 @@
 	u32 xoadc_wakeup;
 };
 
-int32_t pm8058_xoadc_read_adc_code(uint32_t , int32_t *data);
+#ifdef CONFIG_PMIC8058_XOADC
+int32_t pm8058_xoadc_read_adc_code(uint32_t adc_instance, int32_t *data);
 
-int32_t pm8058_xoadc_select_chan_and_start_conv(uint32_t,
-						struct adc_conv_slot *);
+int32_t pm8058_xoadc_select_chan_and_start_conv(uint32_t adc_instance,
+						struct adc_conv_slot *slot);
 
-void pm8058_xoadc_slot_request(uint32_t, struct adc_conv_slot **slot);
+void pm8058_xoadc_slot_request(uint32_t adc_instance,
+		struct adc_conv_slot **slot);
 
-void pm8058_xoadc_restore_slot(uint32_t, struct adc_conv_slot *slot);
+void pm8058_xoadc_restore_slot(uint32_t adc_instance,
+		struct adc_conv_slot *slot);
 
-struct adc_properties *pm8058_xoadc_get_properties(uint32_t);
+struct adc_properties *pm8058_xoadc_get_properties(uint32_t dev_instance);
 
-int32_t pm8058_xoadc_calibrate(uint32_t, struct adc_conv_slot *, int *);
+int32_t pm8058_xoadc_calibrate(uint32_t dev_instance,
+		struct adc_conv_slot *slot, int * calib_status);
 
 int32_t pm8058_xoadc_registered(void);
 
 int32_t pm8058_xoadc_calib_device(uint32_t adc_instance);
+
+#else
+
+static inline int32_t pm8058_xoadc_read_adc_code(uint32_t adc_instance,
+		int32_t *data)
+{ return -ENXIO; }
+
+static inline int32_t pm8058_xoadc_select_chan_and_start_conv(
+		uint32_t adc_instance, struct adc_conv_slot *slot)
+{ return -ENXIO; }
+
+static inline void pm8058_xoadc_slot_request(uint32_t adc_instance,
+		struct adc_conv_slot **slot)
+{ return; }
+
+static inline void pm8058_xoadc_restore_slot(uint32_t adc_instance,
+		struct adc_conv_slot *slot)
+{ return; }
+
+static inline struct adc_properties *pm8058_xoadc_get_properties(
+		uint32_t dev_instance)
+{ return NULL; }
+
+static inline int32_t pm8058_xoadc_calibrate(uint32_t dev_instance,
+		struct adc_conv_slot *slot, int *calib_status)
+{ return -ENXIO; }
+
+static inline int32_t pm8058_xoadc_registered(void)
+{ return -ENXIO; }
+
+static inline int32_t pm8058_xoadc_calib_device(uint32_t adc_instance)
+{ return -ENXIO; }
+#endif
 #endif
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 62d58de..955d229 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -141,6 +141,7 @@
  * @pclk_src_name: pclk is derived from ebi1_usb_clk in case of 7x27 and 8k
  *              dfab_usb_hs_clk in case of 8660 and 8960.
  * @pmic_id_irq: IRQ number assigned for PMIC USB ID line.
+ * @mhl_enable: indicates MHL connector or not.
  */
 struct msm_otg_platform_data {
 	int *phy_init_seq;
@@ -153,6 +154,7 @@
 	void (*setup_gpio)(enum usb_otg_state state);
 	char *pclk_src_name;
 	int pmic_id_irq;
+	bool mhl_enable;
 };
 
 /**
diff --git a/include/media/videobuf2-msm-mem.h b/include/media/videobuf2-msm-mem.h
index ac1575b..916c458 100644
--- a/include/media/videobuf2-msm-mem.h
+++ b/include/media/videobuf2-msm-mem.h
@@ -17,6 +17,7 @@
 
 #include <media/videobuf2-core.h>
 #include <mach/msm_subsystem_map.h>
+#include <linux/ion.h>
 
 struct videobuf2_mapping {
 	unsigned int count;
@@ -58,6 +59,7 @@
 	struct msm_mapped_buffer *msm_buffer;
 	int subsys_id;
 	unsigned long mapped_phyaddr;
+	struct ion_handle *ion_handle;
 };
 void videobuf2_queue_pmem_contig_init(struct vb2_queue *q,
 					enum v4l2_buf_type type,
@@ -70,8 +72,10 @@
 int videobuf2_pmem_contig_user_get(struct videobuf2_contig_pmem *mem,
 					struct videobuf2_msm_offset *offset,
 					enum videobuf2_buffer_type,
-					uint32_t addr_offset, int path);
-void videobuf2_pmem_contig_user_put(struct videobuf2_contig_pmem *mem);
+					uint32_t addr_offset, int path,
+					struct ion_client *client);
+void videobuf2_pmem_contig_user_put(struct videobuf2_contig_pmem *mem,
+					struct ion_client *client);
 unsigned long videobuf2_to_pmem_contig(struct vb2_buffer *buf,
 					unsigned int plane_no);
 
diff --git a/include/sound/apr_audio.h b/include/sound/apr_audio.h
index aff1ce8..9126bbb 100644
--- a/include/sound/apr_audio.h
+++ b/include/sound/apr_audio.h
@@ -870,6 +870,8 @@
 #define G711_MLAW_FS 0x00010BF8
 #define G711_PCM_FS  0x00010BF9
 #define MPEG4_MULTI_AAC 0x00010D86
+#define US_POINT_EPOS_FORMAT 0x00012310
+#define US_RAW_FORMAT        0x0001127C
 
 #define ASM_ENCDEC_SBCRATE         0x00010C13
 #define ASM_ENCDEC_IMMDIATE_DECODE 0x00010C14
diff --git a/include/sound/dai.h b/include/sound/dai.h
index 27ff980..4d3fb96 100644
--- a/include/sound/dai.h
+++ b/include/sound/dai.h
@@ -43,6 +43,7 @@
 void unregister_dma_irq_handler(int dma_ch);
 void dai_set_master_mode(uint32_t dma_ch, int mode);
 int dai_start_hdmi(uint32_t dma_ch);
+int wait_for_dma_cnt_stop(uint32_t dma_ch);
 void dai_stop_hdmi(uint32_t dma_ch);
 
 #endif
diff --git a/include/sound/q6asm.h b/include/sound/q6asm.h
index f146684..16439e8 100644
--- a/include/sound/q6asm.h
+++ b/include/sound/q6asm.h
@@ -147,6 +147,8 @@
 
 struct audio_client *q6asm_audio_client_alloc(app_cb cb, void *priv);
 
+struct audio_client *q6asm_get_audio_client(int session_id);
+
 int q6asm_audio_client_buf_alloc(unsigned int dir/* 1:Out,0:In */,
 				struct audio_client *ac,
 				unsigned int bufsz,
diff --git a/kernel/power/wakelock.c b/kernel/power/wakelock.c
index b257424..892e3ec 100644
--- a/kernel/power/wakelock.c
+++ b/kernel/power/wakelock.c
@@ -19,7 +19,6 @@
 #include <linux/suspend.h>
 #include <linux/syscalls.h> /* sys_sync */
 #include <linux/wakelock.h>
-#include <linux/syscore_ops.h>
 #ifdef CONFIG_WAKELOCK_STAT
 #include <linux/proc_fs.h>
 #endif
@@ -53,8 +52,6 @@
 struct wake_lock main_wake_lock;
 suspend_state_t requested_suspend_state = PM_SUSPEND_MEM;
 static struct wake_lock unknown_wakeup;
-/* flag to warn/bug if wakelocks are taken after suspend_noirq */
-static int msm_suspend_check_done;
 
 #ifdef CONFIG_WAKELOCK_STAT
 static struct wake_lock deleted_wake_locks;
@@ -386,9 +383,6 @@
 #endif
 	if (debug_mask & DEBUG_SUSPEND)
 		pr_info("power_suspend_late return %d\n", ret);
-
-	if (ret == 0)
-		msm_suspend_check_done = 1;
 	return ret;
 }
 
@@ -404,14 +398,6 @@
 	.name = "power",
 };
 
-static void power_resume_early(void)
-{
-	msm_suspend_check_done = 0;
-}
-static struct syscore_ops wakelock_syscore_ops = {
-	.resume = power_resume_early,
-};
-
 void wake_lock_init(struct wake_lock *lock, int type, const char *name)
 {
 	unsigned long irqflags = 0;
@@ -544,24 +530,12 @@
 
 void wake_lock(struct wake_lock *lock)
 {
-	/*
-	 * if wake lock is being called too late in the suspend sequence,
-	 * call bug so we get to analyze the callstack
-	 */
-	BUG_ON(msm_suspend_check_done);
-
 	wake_lock_internal(lock, 0, 0);
 }
 EXPORT_SYMBOL(wake_lock);
 
 void wake_lock_timeout(struct wake_lock *lock, long timeout)
 {
-	/*
-	 * if wake lock is being called too late in the suspend sequence,
-	 * call bug so we get to analyze the callstack
-	 */
-	BUG_ON(msm_suspend_check_done);
-
 	wake_lock_internal(lock, timeout, 1);
 }
 EXPORT_SYMBOL(wake_lock_timeout);
@@ -663,7 +637,6 @@
 	proc_create("wakelocks", S_IRUGO, NULL, &wakelock_stats_fops);
 #endif
 
-	register_syscore_ops(&wakelock_syscore_ops);
 	return 0;
 
 err_suspend_work_queue:
diff --git a/mm/memblock.c b/mm/memblock.c
index a0562d1..5338237 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -38,6 +38,12 @@
 		return "unknown";
 }
 
+/* adjust *@size so that (@base + *@size) doesn't overflow, return new size */
+static inline phys_addr_t memblock_cap_size(phys_addr_t base, phys_addr_t *size)
+{
+	return *size = min(*size, (phys_addr_t)ULLONG_MAX - base);
+}
+
 /*
  * Address comparison utilities
  */
@@ -276,7 +282,7 @@
 static long __init_memblock memblock_add_region(struct memblock_type *type,
 						phys_addr_t base, phys_addr_t size)
 {
-	phys_addr_t end = base + size;
+	phys_addr_t end = base + memblock_cap_size(base, &size);
 	int i, slot = -1;
 
 	/* First try and coalesce this MEMBLOCK with others */
@@ -412,7 +418,7 @@
 static long __init_memblock __memblock_remove(struct memblock_type *type,
 					      phys_addr_t base, phys_addr_t size)
 {
-	phys_addr_t end = base + size;
+	phys_addr_t end = base + memblock_cap_size(base, &size);
 	int i;
 
 	/* Walk through the array for collisions */
@@ -705,16 +711,18 @@
 int __init_memblock memblock_is_region_memory(phys_addr_t base, phys_addr_t size)
 {
 	int idx = memblock_search(&memblock.memory, base);
+	phys_addr_t end = base + memblock_cap_size(base, &size);
 
 	if (idx == -1)
 		return 0;
 	return memblock.memory.regions[idx].base <= base &&
 		(memblock.memory.regions[idx].base +
-		 memblock.memory.regions[idx].size) >= (base + size);
+		 memblock.memory.regions[idx].size) >= end;
 }
 
 int __init_memblock memblock_is_region_reserved(phys_addr_t base, phys_addr_t size)
 {
+	memblock_cap_size(base, &size);
 	return memblock_overlaps_region(&memblock.reserved, base, size) >= 0;
 }
 
diff --git a/sound/soc/msm/lpass-dma.c b/sound/soc/msm/lpass-dma.c
index 84b6f1f..66c1836 100644
--- a/sound/soc/msm/lpass-dma.c
+++ b/sound/soc/msm/lpass-dma.c
@@ -93,6 +93,7 @@
 	spin_lock_irqsave(&dai_lock, flag);
 	intrsrc = readl(dai_info.base + LPAIF_IRQ_STAT(0));
 	writel(intrsrc, dai_info.base + LPAIF_IRQ_CLEAR(0));
+	mb();
 	while (intrsrc) {
 		dma_ch = dai_find_dma_channel(intrsrc);
 
@@ -149,6 +150,7 @@
 			dai_info.base + LPAIF_DMA_BUFF_LEN(dma_ch));
 	writel(((dai[dma_ch]->period_len >> 2) - 1),
 			dai_info.base + LPAIF_DMA_PER_LEN(dma_ch));
+	mb();
 }
 
 static void dai_enable_codec(uint32_t dma_ch, int codec)
@@ -237,6 +239,7 @@
 	dai[dma_ch]->channels = params->channels;
 	dai[dma_ch]->buffer_len = params->buffer_size;
 	dai[dma_ch]->period_len = params->period_size;
+	mb();
 	dai_config_dma(dma_ch);
 	return dma_ch;
 }
@@ -278,6 +281,7 @@
 		val = readl(dai_info.base + LPAIF_IRQ_EN(0));
 		val = val | (7 << (dma_ch * 3));
 		writel(val, dai_info.base + LPAIF_IRQ_EN(0));
+		mb();
 
 
 		val = (HDMI_BURST_INCR4 | HDMI_WPSCNT | HDMI_AUDIO_INTF |
@@ -287,10 +291,58 @@
 	}
 	spin_unlock_irqrestore(&dai_lock, flag);
 
+	mb();
 	dai_print_state(dma_ch);
 	return 0;
 }
 
+int wait_for_dma_cnt_stop(uint32_t dma_ch)
+{
+	uint32_t dma_per_cnt_reg_val, dma_per_cnt, prev_dma_per_cnt;
+	uint32_t i;
+
+	pr_info("%s dma_ch %u\n", __func__, dma_ch);
+
+	dma_per_cnt_reg_val =  readl_relaxed(dai_info.base +
+					LPAIF_DMA_PER_CNT(dma_ch));
+
+	dma_per_cnt =
+		((LPAIF_DMA_PER_CNT_PER_CNT_MASK & dma_per_cnt_reg_val) >>
+			LPAIF_DMA_PER_CNT_PER_CNT_SHIFT) -
+		((LPAIF_DMA_PER_CNT_FIFO_WORDCNT_MASK & dma_per_cnt_reg_val) >>
+			LPAIF_DMA_PER_CNT_FIFO_WORDCNT_SHIFT);
+
+	prev_dma_per_cnt = dma_per_cnt;
+
+	i = 1;
+	pr_info("%s: i = %u dma_per_cnt_reg_val 0x%08x , dma_per_cnt %u\n",
+		__func__, i, dma_per_cnt_reg_val, dma_per_cnt);
+
+	while (i <= 50) {
+		msleep(50);
+
+		dma_per_cnt_reg_val =  readl_relaxed(dai_info.base +
+						LPAIF_DMA_PER_CNT(dma_ch));
+
+		dma_per_cnt =
+		((LPAIF_DMA_PER_CNT_PER_CNT_MASK & dma_per_cnt_reg_val) >>
+			LPAIF_DMA_PER_CNT_PER_CNT_SHIFT) -
+		((LPAIF_DMA_PER_CNT_FIFO_WORDCNT_MASK & dma_per_cnt_reg_val) >>
+			LPAIF_DMA_PER_CNT_FIFO_WORDCNT_SHIFT);
+
+		i++;
+
+		pr_info("%s: i = %u dma_per_cnt_reg_val 0x%08x , dma_per_cnt %u\n",
+			__func__, i, dma_per_cnt_reg_val, dma_per_cnt);
+
+		if (prev_dma_per_cnt == dma_per_cnt)
+			break;
+
+		prev_dma_per_cnt = dma_per_cnt;
+	}
+	return 0;
+}
+
 void dai_stop_hdmi(uint32_t dma_ch)
 {
 	unsigned long flag = 0x0;
@@ -307,14 +359,18 @@
 	intrVal = 0x0;
 	writel(intrVal, dai_info.base + LPAIF_DMA_CTL(dma_ch));
 
+	mb();
+
 	intrVal = readl(dai_info.base + LPAIF_IRQ_EN(0));
 
 	int_mask = ((int_mask) << (dma_ch * 3));
 	int_mask = ~int_mask;
 
-	intrVal = intrVal && int_mask;
+	intrVal = intrVal & int_mask;
 	writel(intrVal, dai_info.base + LPAIF_IRQ_EN(0));
 
+	mb();
+
 	spin_unlock_irqrestore(&dai_lock, flag);
 }
 
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index eb55f77..268d2e5 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -440,6 +440,23 @@
 	return NULL;
 }
 
+struct audio_client *q6asm_get_audio_client(int session_id)
+{
+	if ((session_id <= 0) || (session_id > SESSION_MAX)) {
+		pr_err("%s: invalid session: %d\n", __func__, session_id);
+		goto err;
+	}
+
+	if (!session[session_id]) {
+		pr_err("%s: session not active: %d\n", __func__, session_id);
+		goto err;
+	}
+
+	return session[session_id];
+err:
+	return NULL;
+}
+
 int q6asm_audio_client_buf_alloc(unsigned int dir,
 			struct audio_client *ac,
 			unsigned int bufsz,