Merge changes I3236496a,I579030b3,I428cedee into msm-3.0

* changes:
  mmc: msm_sdcc: don't call udelay() from msmsdcc_delay()
  msm: msm_sdcc: defer device resume until next transfer request comes
  mmc: block: claim host in mmc_blk_set_blksize() only if required
diff --git a/arch/arm/configs/msm-copper_defconfig b/arch/arm/configs/msm-copper_defconfig
index 863a963..d1c607e 100644
--- a/arch/arm/configs/msm-copper_defconfig
+++ b/arch/arm/configs/msm-copper_defconfig
@@ -101,6 +101,9 @@
 CONFIG_SPMI_MSM_PMIC_ARB=y
 CONFIG_MSM_QPNP=y
 CONFIG_MSM_QPNP_INT=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_QUP=y
 CONFIG_DEBUG_GPIO=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_POWER_SUPPLY=y
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index ab3f8da..2ae5230 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -294,6 +294,7 @@
 CONFIG_POWER_SUPPLY=y
 # CONFIG_BATTERY_MSM is not set
 CONFIG_ISL9519_CHARGER=y
+CONFIG_SMB349_CHARGER=y
 CONFIG_PM8921_CHARGER=y
 CONFIG_PM8921_BMS=y
 CONFIG_SENSORS_PM8XXX_ADC=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 75dff22..b2e0786 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -296,6 +296,7 @@
 CONFIG_POWER_SUPPLY=y
 # CONFIG_BATTERY_MSM is not set
 CONFIG_ISL9519_CHARGER=y
+CONFIG_SMB349_CHARGER=y
 CONFIG_PM8921_CHARGER=y
 CONFIG_PM8921_BMS=y
 CONFIG_SENSORS_PM8XXX_ADC=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index c9f5c29..59d2e28 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -2008,6 +2008,10 @@
 config MSM_SLEEP_STATS_DEVICE
 	bool "Enable exporting of MSM sleep device stats to userspace"
 
+config MSM_RUN_QUEUE_STATS
+	bool "Enable collection and exporting of MSM Run Queue stats to userspace"
+	default y
+
 config MSM_STANDALONE_POWER_COLLAPSE
        bool "Enable standalone power collapse"
        default n
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index f71cf6d..7bc2fdd 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -313,9 +313,10 @@
 endif
 endif
 
-obj-$(CONFIG_MSM_SLEEP_STATS) += msm_rq_stats.o idle_stats.o
+obj-$(CONFIG_MSM_SLEEP_STATS) += idle_stats.o
 obj-$(CONFIG_MSM_SLEEP_STATS_DEVICE) += idle_stats_device.o
 obj-$(CONFIG_MSM_DCVS) += msm_dcvs_scm.o msm_dcvs.o msm_dcvs_idle.o
+obj-$(CONFIG_MSM_RUN_QUEUE_STATS) += msm_rq_stats.o
 obj-$(CONFIG_MSM_SHOW_RESUME_IRQ) += msm_show_resume_irq.o
 obj-$(CONFIG_BT_MSM_PINTEST)  += btpintest.o
 obj-$(CONFIG_MSM_FAKE_BATTERY) += fish_battery.o
diff --git a/arch/arm/mach-msm/board-8064-display.c b/arch/arm/mach-msm/board-8064-display.c
index a436f41..433fb2e 100644
--- a/arch/arm/mach-msm/board-8064-display.c
+++ b/arch/arm/mach-msm/board-8064-display.c
@@ -239,7 +239,7 @@
 	.mdp_bus_scale_table = &mdp_bus_scale_pdata,
 	.mdp_rev = MDP_REV_44,
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	.mem_hid = ION_CP_MM_HEAP_ID,
+	.mem_hid = BIT(ION_CP_MM_HEAP_ID),
 #else
 	.mem_hid = MEMTYPE_EBI1,
 #endif
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
index 4b4f32a..ca300e9 100644
--- a/arch/arm/mach-msm/board-8064-pmic.c
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -117,6 +117,7 @@
 	PM8921_GPIO_OUTPUT(23, 0, HIGH),	/* touchscreen power FET */
 	PM8921_GPIO_OUTPUT_BUFCONF(25, 0, LOW, CMOS), /* DISP_RESET_N */
 	PM8921_GPIO_OUTPUT_FUNC(26, 0, PM_GPIO_FUNC_2), /* Bl: Off, PWM mode */
+	PM8921_GPIO_OUTPUT_VIN(30, 1, PM_GPIO_VIN_VPH), /* SMB349 susp line */
 	PM8921_GPIO_OUTPUT_BUFCONF(36, 1, LOW, OPEN_DRAIN),
 	PM8921_GPIO_OUTPUT_FUNC(44, 0, PM_GPIO_FUNC_2),
 	PM8921_GPIO_OUTPUT(33, 0, HIGH),
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 54d68d3..82ce0df 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -15,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/i2c.h>
+#include <linux/i2c/smb349.h>
 #include <linux/slimbus/slimbus.h>
 #include <linux/mfd/wcd9xxx/core.h>
 #include <linux/mfd/wcd9xxx/pdata.h>
@@ -603,6 +604,19 @@
 	}
 }
 
+static struct smb349_platform_data smb349_data __initdata = {
+	.en_n_gpio		= PM8921_GPIO_PM_TO_SYS(37),
+	.chg_susp_gpio		= PM8921_GPIO_PM_TO_SYS(30),
+	.chg_current_ma		= 2200,
+};
+
+static struct i2c_board_info smb349_charger_i2c_info[] __initdata = {
+	{
+		I2C_BOARD_INFO(SMB349_NAME, 0x1B),
+		.platform_data	= &smb349_data,
+	},
+};
+
 #define TABLA_INTERRUPT_BASE (NR_MSM_IRQS + NR_GPIO_IRQS + NR_PM8921_IRQS)
 
 /* Micbias setting is based on 8660 CDP/MTP/FLUID requirement
@@ -2032,6 +2046,12 @@
 
 static struct i2c_registry apq8064_i2c_devices[] __initdata = {
 	{
+		I2C_LIQUID,
+		APQ_8064_GSBI1_QUP_I2C_BUS_ID,
+		smb349_charger_i2c_info,
+		ARRAY_SIZE(smb349_charger_i2c_info)
+	},
+	{
 		I2C_SURF | I2C_LIQUID,
 		APQ_8064_GSBI3_QUP_I2C_BUS_ID,
 		mxt_device_info,
diff --git a/arch/arm/mach-msm/board-8930-display.c b/arch/arm/mach-msm/board-8930-display.c
index 2f18897..c8c631e 100644
--- a/arch/arm/mach-msm/board-8930-display.c
+++ b/arch/arm/mach-msm/board-8930-display.c
@@ -441,7 +441,7 @@
 #endif
 	.mdp_rev = MDP_REV_42,
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	.mem_hid = ION_CP_MM_HEAP_ID,
+	.mem_hid = BIT(ION_CP_MM_HEAP_ID),
 #else
 	.mem_hid = MEMTYPE_EBI1,
 #endif
diff --git a/arch/arm/mach-msm/board-8960-display.c b/arch/arm/mach-msm/board-8960-display.c
index 61bf9fc..2a29ad0 100644
--- a/arch/arm/mach-msm/board-8960-display.c
+++ b/arch/arm/mach-msm/board-8960-display.c
@@ -704,7 +704,7 @@
 #endif
 	.mdp_rev = MDP_REV_42,
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	.mem_hid = ION_CP_MM_HEAP_ID,
+	.mem_hid = BIT(ION_CP_MM_HEAP_ID),
 #else
 	.mem_hid = MEMTYPE_EBI1,
 #endif
diff --git a/arch/arm/mach-msm/board-8960-pmic.c b/arch/arm/mach-msm/board-8960-pmic.c
index c71e657..3bf1297 100644
--- a/arch/arm/mach-msm/board-8960-pmic.c
+++ b/arch/arm/mach-msm/board-8960-pmic.c
@@ -101,8 +101,8 @@
 	PM8XXX_GPIO_INPUT(16,	    PM_GPIO_PULL_UP_30), /* SD_CARD_WP */
     /* External regulator shared by display and touchscreen on LiQUID */
 	PM8XXX_GPIO_OUTPUT(17,	    0),			 /* DISP 3.3 V Boost */
-	PM8XXX_GPIO_OUTPUT(18,	1),	/* TABLA SPKR_LEFT_EN */
-	PM8XXX_GPIO_OUTPUT(19,	1),	/* TABLA SPKR_RIGHT_EN */
+	PM8XXX_GPIO_OUTPUT(18,	0),	/* TABLA SPKR_LEFT_EN=off */
+	PM8XXX_GPIO_OUTPUT(19,	0),	/* TABLA SPKR_RIGHT_EN=off */
 	PM8XXX_GPIO_DISABLE(22),			 /* Disable NFC */
 	PM8XXX_GPIO_OUTPUT_FUNC(25, 0, PM_GPIO_FUNC_2),	 /* TN_CLK */
 	PM8XXX_GPIO_INPUT(26,	    PM_GPIO_PULL_UP_30), /* SD_CARD_DET_N */
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index 40cd9ea..3438f9d 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -374,9 +374,8 @@
 #define USB_BAM_PHY_BASE	0x12502000
 #define HSIC_BAM_PHY_BASE	0x12542000
 #define A2_BAM_PHY_BASE		0x124C2000
-static struct usb_bam_pipe_connect msm_usb_bam_connections[4][2] = {
-#ifndef CONFIG_USB_CI13XXX_MSM_HSIC
-	[0][USB_TO_PEER_PERIPHERAL] = {
+static struct usb_bam_pipe_connect msm_usb_bam_connections[2][4][2] = {
+	[0][0][USB_TO_PEER_PERIPHERAL] = {
 		.src_phy_addr = USB_BAM_PHY_BASE,
 		.src_pipe_index = 11,
 		.dst_phy_addr = A2_BAM_PHY_BASE,
@@ -386,7 +385,7 @@
 		.desc_fifo_base_offset = 0x1700,
 		.desc_fifo_size = 0x300,
 	},
-	[0][PEER_PERIPHERAL_TO_USB] = {
+	[0][0][PEER_PERIPHERAL_TO_USB] = {
 		.src_phy_addr = A2_BAM_PHY_BASE,
 		.src_pipe_index = 1,
 		.dst_phy_addr = USB_BAM_PHY_BASE,
@@ -396,7 +395,7 @@
 		.desc_fifo_base_offset = 0x1000,
 		.desc_fifo_size = 0x100,
 	},
-	[1][USB_TO_PEER_PERIPHERAL] = {
+	[0][1][USB_TO_PEER_PERIPHERAL] = {
 		.src_phy_addr = USB_BAM_PHY_BASE,
 		.src_pipe_index = 13,
 		.dst_phy_addr = A2_BAM_PHY_BASE,
@@ -406,7 +405,7 @@
 		.desc_fifo_base_offset = 0x2700,
 		.desc_fifo_size = 0x300,
 	},
-	[1][PEER_PERIPHERAL_TO_USB] = {
+	[0][1][PEER_PERIPHERAL_TO_USB] = {
 		.src_phy_addr = A2_BAM_PHY_BASE,
 		.src_pipe_index = 3,
 		.dst_phy_addr = USB_BAM_PHY_BASE,
@@ -416,7 +415,7 @@
 		.desc_fifo_base_offset = 0x2000,
 		.desc_fifo_size = 0x100,
 	},
-	[2][USB_TO_PEER_PERIPHERAL] = {
+	[0][2][USB_TO_PEER_PERIPHERAL] = {
 		.src_phy_addr = USB_BAM_PHY_BASE,
 		.src_pipe_index = 15,
 		.dst_phy_addr = A2_BAM_PHY_BASE,
@@ -426,7 +425,7 @@
 		.desc_fifo_base_offset = 0x3700,
 		.desc_fifo_size = 0x300,
 	},
-	[2][PEER_PERIPHERAL_TO_USB] = {
+	[0][2][PEER_PERIPHERAL_TO_USB] = {
 		.src_phy_addr = A2_BAM_PHY_BASE,
 		.src_pipe_index = 5,
 		.dst_phy_addr = USB_BAM_PHY_BASE,
@@ -435,9 +434,8 @@
 		.data_fifo_size = 0x600,
 		.desc_fifo_base_offset = 0x3000,
 		.desc_fifo_size = 0x100,
-	}
-#else
-	[0][USB_TO_PEER_PERIPHERAL] = {
+	},
+	[1][0][USB_TO_PEER_PERIPHERAL] = {
 		.src_phy_addr = HSIC_BAM_PHY_BASE,
 		.src_pipe_index = 1,
 		.dst_phy_addr = A2_BAM_PHY_BASE,
@@ -447,7 +445,7 @@
 		.desc_fifo_base_offset = 0x1700,
 		.desc_fifo_size = 0x300,
 	},
-	[0][PEER_PERIPHERAL_TO_USB] = {
+	[1][0][PEER_PERIPHERAL_TO_USB] = {
 		.src_phy_addr = A2_BAM_PHY_BASE,
 		.src_pipe_index = 1,
 		.dst_phy_addr = HSIC_BAM_PHY_BASE,
@@ -457,7 +455,7 @@
 		.desc_fifo_base_offset = 0x1000,
 		.desc_fifo_size = 0x100,
 	},
-	[1][USB_TO_PEER_PERIPHERAL] = {
+	[1][1][USB_TO_PEER_PERIPHERAL] = {
 		.src_phy_addr = HSIC_BAM_PHY_BASE,
 		.src_pipe_index = 3,
 		.dst_phy_addr = A2_BAM_PHY_BASE,
@@ -467,7 +465,7 @@
 		.desc_fifo_base_offset = 0x2700,
 		.desc_fifo_size = 0x300,
 	},
-	[1][PEER_PERIPHERAL_TO_USB] = {
+	[1][1][PEER_PERIPHERAL_TO_USB] = {
 		.src_phy_addr = A2_BAM_PHY_BASE,
 		.src_pipe_index = 3,
 		.dst_phy_addr = HSIC_BAM_PHY_BASE,
@@ -477,7 +475,7 @@
 		.desc_fifo_base_offset = 0x2000,
 		.desc_fifo_size = 0x100,
 	},
-	[2][USB_TO_PEER_PERIPHERAL] = {
+	[1][2][USB_TO_PEER_PERIPHERAL] = {
 		.src_phy_addr = HSIC_BAM_PHY_BASE,
 		.src_pipe_index = 5,
 		.dst_phy_addr = A2_BAM_PHY_BASE,
@@ -487,7 +485,7 @@
 		.desc_fifo_base_offset = 0x3700,
 		.desc_fifo_size = 0x300,
 	},
-	[2][PEER_PERIPHERAL_TO_USB] = {
+	[1][2][PEER_PERIPHERAL_TO_USB] = {
 		.src_phy_addr = A2_BAM_PHY_BASE,
 		.src_pipe_index = 5,
 		.dst_phy_addr = HSIC_BAM_PHY_BASE,
@@ -497,18 +495,16 @@
 		.desc_fifo_base_offset = 0x3000,
 		.desc_fifo_size = 0x100,
 	}
-#endif
 };
 
 static struct msm_usb_bam_platform_data msm_usb_bam_pdata = {
-	.connections = &msm_usb_bam_connections[0][0],
+	.connections = &msm_usb_bam_connections[0][0][0],
 #ifndef CONFIG_USB_CI13XXX_MSM_HSIC
 	.usb_active_bam = HSUSB_BAM,
-	.usb_bam_num_pipes = 16,
 #else
 	.usb_active_bam = HSIC_BAM,
-	.usb_bam_num_pipes = 16,
 #endif
+	.usb_bam_num_pipes = 16,
 };
 
 static struct msm_otg_platform_data msm_otg_pdata = {
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 28d1cf0..e75a963 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -1375,6 +1375,8 @@
 				ARRAY_SIZE(msm7x27a_pm_data));
 		BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
 	}
+
+	msm_pm_register_irqs();
 }
 
 static void __init msm7x2x_init(void)
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index 1e4ebdcd..cd1e5b8 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -6820,6 +6820,7 @@
 	msm_fb_add_devices();
 	msm_pm_set_platform_data(msm_pm_data, ARRAY_SIZE(msm_pm_data));
 	BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
+	msm_pm_register_irqs();
 	msm_device_i2c_init();
 	msm_device_i2c_2_init();
 	qup_device_i2c_init();
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 70efcce..f181133 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -9710,7 +9710,7 @@
 #endif
 	.mdp_rev = MDP_REV_41,
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-	.mem_hid = ION_CP_WB_HEAP_ID,
+	.mem_hid = BIT(ION_CP_WB_HEAP_ID),
 #else
 	.mem_hid = MEMTYPE_EBI1,
 #endif
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index 3c01115..ad4114d 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -1323,6 +1323,7 @@
 #endif
 	msm_pm_init();
 
+	msm_pm_register_irqs();
 	msm_fb_add_devices();
 
 #if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c
index 5a77333..239896a 100644
--- a/arch/arm/mach-msm/board-qsd8x50.c
+++ b/arch/arm/mach-msm/board-qsd8x50.c
@@ -55,6 +55,7 @@
 #include "msm-keypad-devices.h"
 #include "acpuclock.h"
 #include "pm.h"
+#include "irq.h"
 #include "pm-boot.h"
 #include "proc_comm.h"
 #ifdef CONFIG_USB_ANDROID
@@ -2442,6 +2443,7 @@
 				ARRAY_SIZE(msm_spi_board_info));
 	msm_pm_set_platform_data(msm_pm_data, ARRAY_SIZE(msm_pm_data));
 	BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
+	msm_pm_register_irqs();
 
 #ifdef CONFIG_SURF_FFA_GPIO_KEYPAD
 	if (machine_is_qsd8x50_ffa())
diff --git a/arch/arm/mach-msm/devices-msm7x27.c b/arch/arm/mach-msm/devices-msm7x27.c
index 26f246d..3008fe9 100644
--- a/arch/arm/mach-msm/devices-msm7x27.c
+++ b/arch/arm/mach-msm/devices-msm7x27.c
@@ -35,6 +35,8 @@
 #include <mach/msm_hsusb.h>
 #include <mach/usbdiag.h>
 #include <mach/rpc_hsusb.h>
+#include "irq.h"
+#include "pm.h"
 
 static struct resource resources_uart1[] = {
 	{
@@ -415,6 +417,21 @@
 	},
 };
 
+static struct msm_pm_irq_calls msm7x27_pm_irq_calls = {
+	.irq_pending = msm_irq_pending,
+	.idle_sleep_allowed = msm_irq_idle_sleep_allowed,
+	.enter_sleep1 = msm_irq_enter_sleep1,
+	.enter_sleep2 = msm_irq_enter_sleep2,
+	.exit_sleep1 = msm_irq_exit_sleep1,
+	.exit_sleep2 = msm_irq_exit_sleep2,
+	.exit_sleep3 = msm_irq_exit_sleep3,
+};
+
+void msm_pm_register_irqs(void)
+{
+	msm_pm_set_irq_extns(&msm7x27_pm_irq_calls);
+}
+
 #define MSM_SDC1_BASE         0xA0400000
 #define MSM_SDC2_BASE         0xA0500000
 #define MSM_SDC3_BASE         0xA0600000
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index b879d8b..8236e1e 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -35,6 +35,8 @@
 #include "acpuclock.h"
 #include "spm.h"
 #include "mpm-8625.h"
+#include "irq.h"
+#include "pm.h"
 
 /* Address of GSBI blocks */
 #define MSM_GSBI0_PHYS		0xA1200000
@@ -425,6 +427,35 @@
 	},
 };
 
+static struct msm_pm_irq_calls msm7x27a_pm_irq_calls = {
+	.irq_pending = msm_irq_pending,
+	.idle_sleep_allowed = msm_irq_idle_sleep_allowed,
+	.enter_sleep1 = msm_irq_enter_sleep1,
+	.enter_sleep2 = msm_irq_enter_sleep2,
+	.exit_sleep1 = msm_irq_exit_sleep1,
+	.exit_sleep2 = msm_irq_exit_sleep2,
+	.exit_sleep3 = msm_irq_exit_sleep3,
+};
+
+static struct msm_pm_irq_calls msm8625_pm_irq_calls = {
+	.irq_pending = msm_gic_spi_ppi_pending,
+	.idle_sleep_allowed = msm_gic_irq_idle_sleep_allowed,
+	.enter_sleep1 = msm_gic_irq_enter_sleep1,
+	.enter_sleep2 = msm_gic_irq_enter_sleep2,
+	.exit_sleep1 = msm_gic_irq_exit_sleep1,
+	.exit_sleep2 = msm_gic_irq_exit_sleep2,
+	.exit_sleep3 = msm_gic_irq_exit_sleep3,
+};
+
+void msm_pm_register_irqs(void)
+{
+	if (cpu_is_msm8625())
+		msm_pm_set_irq_extns(&msm8625_pm_irq_calls);
+	else
+		msm_pm_set_irq_extns(&msm7x27a_pm_irq_calls);
+
+}
+
 #define MSM_SDC1_BASE         0xA0400000
 #define MSM_SDC2_BASE         0xA0500000
 #define MSM_SDC3_BASE         0xA0600000
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
index e0c23fa..17e7364 100644
--- a/arch/arm/mach-msm/devices-msm7x30.c
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -40,6 +40,8 @@
 #endif
 #include <mach/dal_axi.h>
 #include <mach/msm_memtypes.h>
+#include "pm.h"
+#include "irq.h"
 
 /* EBI THERMAL DRIVER */
 static struct resource msm_ebi0_thermal_resources[] = {
@@ -595,6 +597,21 @@
 	},
 };
 
+static struct msm_pm_irq_calls msm7x30_pm_irq_calls = {
+	.irq_pending = msm_irq_pending,
+	.idle_sleep_allowed = msm_irq_idle_sleep_allowed,
+	.enter_sleep1 = msm_irq_enter_sleep1,
+	.enter_sleep2 = msm_irq_enter_sleep2,
+	.exit_sleep1 = msm_irq_exit_sleep1,
+	.exit_sleep2 = msm_irq_exit_sleep2,
+	.exit_sleep3 = msm_irq_exit_sleep3,
+};
+
+void msm_pm_register_irqs(void)
+{
+	msm_pm_set_irq_extns(&msm7x30_pm_irq_calls);
+}
+
 static struct resource smd_resource[] = {
 	{
 		.name   = "a9_m2a_0",
diff --git a/arch/arm/mach-msm/devices-qsd8x50.c b/arch/arm/mach-msm/devices-qsd8x50.c
index 05efcdf..a32079b 100644
--- a/arch/arm/mach-msm/devices-qsd8x50.c
+++ b/arch/arm/mach-msm/devices-qsd8x50.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -33,6 +33,7 @@
 #include <mach/msm_hsusb.h>
 #include <mach/usbdiag.h>
 #include <mach/rpc_hsusb.h>
+#include "pm.h"
 
 static struct resource resources_uart1[] = {
 	{
@@ -432,6 +433,21 @@
 	},
 };
 
+static struct msm_pm_irq_calls qsd8x50_pm_irq_calls = {
+	.irq_pending = msm_irq_pending,
+	.idle_sleep_allowed = msm_irq_idle_sleep_allowed,
+	.enter_sleep1 = msm_irq_enter_sleep1,
+	.enter_sleep2 = msm_irq_enter_sleep2,
+	.exit_sleep1 = msm_irq_exit_sleep1,
+	.exit_sleep2 = msm_irq_exit_sleep2,
+	.exit_sleep3 = msm_irq_exit_sleep3,
+};
+
+void msm_pm_register_irqs(void)
+{
+	msm_pm_set_irq_extns(&qsd8x50_pm_irq_calls);
+}
+
 struct platform_device msm_device_smd = {
 	.name	= "msm_smd",
 	.id	= -1,
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index 66299a4..ae4d632 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -513,6 +513,7 @@
 int msm_add_sdcc(unsigned int controller,
 		struct mmc_platform_data *plat);
 
+void msm_pm_register_irqs(void);
 struct msm_usb_host_platform_data;
 int msm_add_host(unsigned int host,
 		struct msm_usb_host_platform_data *plat);
diff --git a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppcmdi.h b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppcmdi.h
index c580774..86216d4 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppcmdi.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5/qdsp5audppcmdi.h
@@ -15,7 +15,7 @@
 EXTERNALIZED FUNCTIONS
   None
 
-Copyright (c) 1992-2009, Code Aurora Forum. All rights reserved.
+Copyright(c) 1992-2009, 2012 Code Aurora Forum. All rights reserved.
 
 This software is licensed under the terms of the GNU General Public
 License version 2, as published by the Free Software Foundation, and
@@ -958,6 +958,12 @@
 #define AUDPP_CMD_CMD_TYPE_OBJ		0x0015
 #define AUDPP_CMD_CMD_TYPE_QUERY	0x1000
 
+#define SRS_PARAMS_MAX_G 8
+#define SRS_PARAMS_MAX_W 55
+#define SRS_PARAMS_MAX_C 51
+#define SRS_PARAMS_MAX_H 53
+#define SRS_PARAMS_MAX_P 116
+#define SRS_PARAMS_MAX_L 8
 
 typedef struct {
 	unsigned short			cmd_id;
@@ -999,6 +1005,33 @@
 	unsigned short			absolute_gain;
 } __attribute__((packed)) audpp_cmd_reverb_config_env_15;
 
+/*
+ * Command Structure to configure post processing params (SRS TruMedia)
+ */
+struct audpp_cmd_cfg_object_params_srstm_g {
+	audpp_cmd_cfg_object_params_common	common;
+	unsigned short				v[SRS_PARAMS_MAX_G];
+} __packed;
+struct audpp_cmd_cfg_object_params_srstm_w {
+	audpp_cmd_cfg_object_params_common	common;
+	unsigned short				v[SRS_PARAMS_MAX_W];
+} __packed;
+struct audpp_cmd_cfg_object_params_srstm_c {
+	audpp_cmd_cfg_object_params_common	common;
+	unsigned short				v[SRS_PARAMS_MAX_C];
+} __packed;
+struct audpp_cmd_cfg_object_params_srstm_h {
+	audpp_cmd_cfg_object_params_common	common;
+	unsigned short				v[SRS_PARAMS_MAX_H];
+} __packed;
+struct audpp_cmd_cfg_object_params_srstm_p {
+	audpp_cmd_cfg_object_params_common	common;
+	unsigned short				v[SRS_PARAMS_MAX_P];
+} __packed;
+struct audpp_cmd_cfg_object_params_srstm_l {
+	audpp_cmd_cfg_object_params_common	common;
+	unsigned short				v[SRS_PARAMS_MAX_L];
+} __packed;
 
 #endif /* QDSP5AUDPPCMDI_H */
 
diff --git a/arch/arm/mach-msm/msm_rq_stats.c b/arch/arm/mach-msm/msm_rq_stats.c
index 492612f..9d14d56 100644
--- a/arch/arm/mach-msm/msm_rq_stats.c
+++ b/arch/arm/mach-msm/msm_rq_stats.c
@@ -26,6 +26,7 @@
 #include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/rq_stats.h>
+#include <asm/smp_plat.h>
 
 #define MAX_LONG_SIZE 24
 #define DEFAULT_RQ_POLL_JIFFIES 1
@@ -197,6 +198,12 @@
 {
 	int ret;
 
+	/* Bail out if this is not an SMP Target */
+	if (!is_smp()) {
+		rq_info.init = 0;
+		return -ENOSYS;
+	}
+
 	rq_wq = create_singlethread_workqueue("rq_stats");
 	BUG_ON(!rq_wq);
 	INIT_WORK(&rq_info.def_timer_work, def_work_fn);
diff --git a/arch/arm/mach-msm/pm.h b/arch/arm/mach-msm/pm.h
index 4e9cc3c..caafbdd 100644
--- a/arch/arm/mach-msm/pm.h
+++ b/arch/arm/mach-msm/pm.h
@@ -29,6 +29,20 @@
 
 extern int power_collapsed;
 
+struct msm_pm_irq_calls {
+	unsigned int (*irq_pending)(void);
+	int (*idle_sleep_allowed)(void);
+	void (*enter_sleep1)(bool modem_wake, int from_idle, uint32_t
+								*irq_mask);
+	int (*enter_sleep2)(bool modem_wake, int from_idle);
+	void (*exit_sleep1)(uint32_t irq_mask, uint32_t wakeup_reason,
+							uint32_t pending_irqs);
+	void (*exit_sleep2)(uint32_t irq_mask, uint32_t wakeup_reason,
+							uint32_t pending_irqs);
+	void (*exit_sleep3)(uint32_t irq_mask, uint32_t wakeup_reason,
+							uint32_t pending_irqs);
+};
+
 enum msm_pm_sleep_mode {
 	MSM_PM_SLEEP_MODE_POWER_COLLAPSE_SUSPEND,
 	MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
@@ -60,6 +74,7 @@
 };
 
 void msm_pm_set_platform_data(struct msm_pm_platform_data *data, int count);
+void msm_pm_set_irq_extns(struct msm_pm_irq_calls *irq_calls);
 int msm_pm_idle_prepare(struct cpuidle_device *dev);
 int msm_pm_idle_enter(enum msm_pm_sleep_mode sleep_mode);
 void msm_pm_cpu_enter_lowpower(unsigned int cpu);
diff --git a/arch/arm/mach-msm/pm2.c b/arch/arm/mach-msm/pm2.c
index 94bc98f..6dc1859 100644
--- a/arch/arm/mach-msm/pm2.c
+++ b/arch/arm/mach-msm/pm2.c
@@ -155,6 +155,7 @@
 };
 
 static struct msm_pm_platform_data *msm_pm_modes;
+static struct msm_pm_irq_calls *msm_pm_irq_extns;
 
 struct msm_pm_kobj_attribute {
 	unsigned int cpu;
@@ -398,6 +399,19 @@
 	msm_pm_modes = data;
 }
 
+void __init msm_pm_set_irq_extns(struct msm_pm_irq_calls *irq_calls)
+{
+	/* sanity check */
+	BUG_ON(irq_calls == NULL || irq_calls->irq_pending == NULL ||
+		irq_calls->idle_sleep_allowed == NULL ||
+		irq_calls->enter_sleep1 == NULL ||
+		irq_calls->enter_sleep2 == NULL ||
+		irq_calls->exit_sleep1 == NULL ||
+		irq_calls->exit_sleep2 == NULL ||
+		irq_calls->exit_sleep3 == NULL);
+
+	msm_pm_irq_extns = irq_calls;
+}
 
 /******************************************************************************
  * Sleep Limitations
@@ -1015,7 +1029,8 @@
 		WARN_ON(ret);
 	}
 
-	msm_irq_enter_sleep1(true, from_idle, &msm_pm_smem_data->irq_mask);
+	msm_pm_irq_extns->enter_sleep1(true, from_idle,
+						&msm_pm_smem_data->irq_mask);
 	msm_sirc_enter_sleep();
 	msm_gpio_enter_sleep(from_idle);
 
@@ -1061,7 +1076,7 @@
 
 	MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): PWRC RSA");
 
-	ret = msm_irq_enter_sleep2(true, from_idle);
+	ret = msm_pm_irq_extns->enter_sleep2(true, from_idle);
 	if (ret < 0) {
 		MSM_PM_DPRINTK(
 			MSM_PM_DEBUG_SUSPEND|MSM_PM_DEBUG_POWER_COLLAPSE,
@@ -1125,7 +1140,7 @@
 		printk(KERN_ERR "%s(): failed to restore clock rate(%lu)\n",
 			__func__, saved_acpuclk_rate);
 
-	msm_irq_exit_sleep1(msm_pm_smem_data->irq_mask,
+	msm_pm_irq_extns->exit_sleep1(msm_pm_smem_data->irq_mask,
 		msm_pm_smem_data->wakeup_reason,
 		msm_pm_smem_data->pending_irqs);
 
@@ -1202,10 +1217,10 @@
 	MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): WFPI RUN");
 	MSM_PM_DEBUG_PRINT_SLEEP_INFO();
 
-	msm_irq_exit_sleep2(msm_pm_smem_data->irq_mask,
+	msm_pm_irq_extns->exit_sleep2(msm_pm_smem_data->irq_mask,
 		msm_pm_smem_data->wakeup_reason,
 		msm_pm_smem_data->pending_irqs);
-	msm_irq_exit_sleep3(msm_pm_smem_data->irq_mask,
+	msm_pm_irq_extns->exit_sleep3(msm_pm_smem_data->irq_mask,
 		msm_pm_smem_data->wakeup_reason,
 		msm_pm_smem_data->pending_irqs);
 	msm_gpio_exit_sleep();
@@ -1438,7 +1453,7 @@
 #ifdef CONFIG_HAS_WAKELOCK
 		has_wake_lock(WAKE_LOCK_IDLE) ||
 #endif
-		!msm_irq_idle_sleep_allowed()) {
+		!msm_pm_irq_extns->idle_sleep_allowed()) {
 		allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE] = false;
 		allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN] = false;
 	}
@@ -1521,7 +1536,7 @@
 	} else if (allow[MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT]) {
 		ret = msm_pm_swfi(true);
 		if (ret)
-			while (!msm_irq_pending())
+			while (!msm_pm_irq_extns->irq_pending())
 				udelay(1);
 		low_power = 0;
 #ifdef CONFIG_MSM_IDLE_STATS
@@ -1534,7 +1549,7 @@
 		exit_stat = MSM_PM_STAT_IDLE_WFI;
 #endif
 	} else {
-		while (!msm_irq_pending())
+		while (!msm_pm_irq_extns->irq_pending())
 			udelay(1);
 		low_power = 0;
 #ifdef CONFIG_MSM_IDLE_STATS
@@ -1656,7 +1671,7 @@
 	} else if (allow[MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT]) {
 		ret = msm_pm_swfi(true);
 		if (ret)
-			while (!msm_irq_pending())
+			while (!msm_pm_irq_extns->irq_pending())
 				udelay(1);
 	} else if (allow[MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT]) {
 		msm_pm_swfi(false);
diff --git a/arch/arm/mach-msm/qdsp5/audio_out.c b/arch/arm/mach-msm/qdsp5/audio_out.c
index 7d33e05..8fe8cf66 100644
--- a/arch/arm/mach-msm/qdsp5/audio_out.c
+++ b/arch/arm/mach-msm/qdsp5/audio_out.c
@@ -4,6 +4,7 @@
  *
  * Copyright (C) 2008 Google, Inc.
  * Copyright (C) 2008 HTC Corporation
+ * Copyright (c) 2012 Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -21,6 +22,7 @@
 #include <linux/miscdevice.h>
 #include <linux/uaccess.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 #include <linux/wait.h>
 #include <linux/dma-mapping.h>
 #include <linux/debugfs.h>
@@ -46,6 +48,21 @@
 #define LOG_AUDIO_EVENTS 1
 #define LOG_AUDIO_FAULTS 0
 
+#define SRS_ID_GLOBAL			0x00000001
+#define SRS_ID_WOWHD			0x00000002
+#define SRS_ID_CSHP			0x00000003
+#define SRS_ID_HPF			0x00000004
+#define SRS_ID_PEQ			0x00000005
+#define SRS_ID_HL			0x00000006
+
+#define SRS_MASK_G 1
+#define SRS_MASK_W 2
+#define SRS_MASK_C 4
+#define SRS_MASK_HP 8
+#define SRS_MASK_P 16
+#define SRS_MASK_HL 32
+
+
 enum {
 	EV_NULL,
 	EV_OPEN,
@@ -163,6 +180,10 @@
 
 	int qconcert_plus_enable;
 	int qconcert_plus_needs_commit;
+
+	int srs_enable;
+	int srs_needs_commit;
+	int srs_feature_mask;
 	audpp_cmd_cfg_object_params_qconcert qconcert_plus;
 
 	int status;
@@ -170,6 +191,13 @@
 	struct mutex lock;
 
 	struct audpp_event_callback ecb;
+
+	struct audpp_cmd_cfg_object_params_srstm_g g;
+	struct audpp_cmd_cfg_object_params_srstm_w w;
+	struct audpp_cmd_cfg_object_params_srstm_c c;
+	struct audpp_cmd_cfg_object_params_srstm_h h;
+	struct audpp_cmd_cfg_object_params_srstm_p p;
+	struct audpp_cmd_cfg_object_params_srstm_l l;
 } the_audio_copp;
 
 static void audio_prevent_sleep(struct audio *audio)
@@ -190,7 +218,7 @@
 static int audio_dsp_send_buffer(struct audio *audio, unsigned id, unsigned len);
 
 static void audio_dsp_event(void *private, unsigned id, uint16_t *msg);
-
+static int audio_enable_srs_trumedia(struct audio_copp *audio_copp, int enable);
 /* must be called with audio->lock held */
 static int audio_enable(struct audio *audio)
 {
@@ -279,6 +307,7 @@
 	audpp_dsp_set_qconcert_plus(COMMON_OBJ_ID,
 				audio_copp->qconcert_plus_enable,
 				&audio_copp->qconcert_plus);
+	audio_enable_srs_trumedia(audio_copp, true);
 }
 EXPORT_SYMBOL(audio_commit_pending_pp_params);
 
@@ -448,6 +477,37 @@
 	return 0;
 }
 
+static int audio_enable_srs_trumedia(struct audio_copp *audio_copp, int enable)
+{
+
+	if (!audio_copp->srs_needs_commit)
+		return 0;
+
+	audio_copp->srs_enable = enable;
+
+	MM_DBG("Enable SRS flags 0x%x enable %d\n",
+		audio_copp->srs_feature_mask, enable);
+	if (is_audpp_enable()) {
+		MM_DBG("Updating audpp for srs\n");
+		if (audio_copp->srs_feature_mask & SRS_MASK_W)
+			audpp_dsp_set_rx_srs_trumedia_w(&audio_copp->w);
+		if (audio_copp->srs_feature_mask & SRS_MASK_C)
+			audpp_dsp_set_rx_srs_trumedia_c(&audio_copp->c);
+		if (audio_copp->srs_feature_mask & SRS_MASK_HP)
+			audpp_dsp_set_rx_srs_trumedia_h(&audio_copp->h);
+		if (audio_copp->srs_feature_mask & SRS_MASK_P)
+			audpp_dsp_set_rx_srs_trumedia_p(&audio_copp->p);
+		if (audio_copp->srs_feature_mask & SRS_MASK_HL)
+			audpp_dsp_set_rx_srs_trumedia_l(&audio_copp->l);
+		if (audio_copp->srs_feature_mask & SRS_MASK_G)
+			audpp_dsp_set_rx_srs_trumedia_g(&audio_copp->g);
+
+		audio_copp->srs_needs_commit = 0;
+		audio_copp->srs_feature_mask = 0;
+	}
+	return 0;
+}
+
 static int audio_enable_vol_pan(struct audio_copp *audio_copp)
 {
 	if (is_audpp_enable())
@@ -785,6 +845,8 @@
 	int rc = 0, enable;
 	uint16_t enable_mask;
 	int prev_state;
+	uint32_t to_set, size = 0;
+	void *tmpbuf, *srs_params = NULL;
 
 	mutex_lock(&audio_copp->lock);
 	switch (cmd) {
@@ -804,6 +866,8 @@
 		audio_enable_rx_iir(audio_copp, enable);
 		enable = (enable_mask & QCONCERT_PLUS_ENABLE) ? 1 : 0;
 		audio_enable_qconcert_plus(audio_copp, enable);
+		enable = (enable_mask & SRS_ENABLE) ? 1 : 0;
+		audio_enable_srs_trumedia(audio_copp, enable);
 		break;
 
 	case AUDIO_SET_MBADRC: {
@@ -916,6 +980,75 @@
 		audio_copp->qconcert_plus_needs_commit = 1;
 		break;
 
+	case AUDIO_SET_SRS_TRUMEDIA_PARAM: {
+		prev_state = audio_copp->srs_enable;
+		audio_copp->srs_enable = 0;
+
+		if (copy_from_user(&to_set, (void *)arg, sizeof(uint32_t))) {
+			rc = -EFAULT;
+			break;
+		}
+		switch (to_set) {
+		case SRS_ID_GLOBAL:
+			srs_params = (void *)audio_copp->g.v;
+			size = sizeof(audio_copp->g.v);
+			audio_copp->srs_feature_mask |= SRS_MASK_G;
+			break;
+		case SRS_ID_WOWHD:
+			srs_params = (void *)audio_copp->w.v;
+			size = sizeof(audio_copp->w.v);
+			audio_copp->srs_feature_mask |= SRS_MASK_W;
+			break;
+		case SRS_ID_CSHP:
+			srs_params = (void *)audio_copp->c.v;
+			size = sizeof(audio_copp->c.v);
+			audio_copp->srs_feature_mask |= SRS_MASK_C;
+			break;
+		case SRS_ID_HPF:
+			srs_params = (void *)audio_copp->h.v;
+			size = sizeof(audio_copp->h.v);
+			audio_copp->srs_feature_mask |= SRS_MASK_HP;
+			break;
+		case SRS_ID_PEQ:
+			srs_params = (void *)audio_copp->p.v;
+			size = sizeof(audio_copp->p.v);
+			audio_copp->srs_feature_mask |= SRS_MASK_P;
+			break;
+		case SRS_ID_HL:
+			srs_params = (void *)audio_copp->l.v;
+			size = sizeof(audio_copp->l.v);
+			audio_copp->srs_feature_mask |= SRS_MASK_HL;
+			break;
+		default:
+			MM_ERR("SRS TruMedia error: invalid ioctl\n");
+			rc = -EINVAL;
+		}
+
+		if (rc >= 0) {
+			tmpbuf = kzalloc(sizeof(uint32_t) + size , GFP_KERNEL);
+			if (!tmpbuf) {
+				MM_ERR("SRS TruMedia error: no kernel mem\n");
+				rc = -ENOMEM;
+			} else {
+				if (copy_from_user(tmpbuf, (void *)arg,
+						sizeof(uint32_t) + size))
+					rc = -EFAULT;
+				memcpy(srs_params,
+					&(((uint32_t *)tmpbuf)[1]), size);
+				kfree(tmpbuf);
+			}
+		}
+
+		MM_DBG("Ioctl SRS flags=0x%x\n", audio_copp->srs_feature_mask);
+		if (rc < 0)
+			MM_ERR("SRS TruMedia error setting params failed.\n");
+		else{
+			audio_copp->srs_needs_commit = 1;
+			audio_copp->srs_enable = prev_state;
+		}
+		break;
+	}
+
 	default:
 		rc = -EINVAL;
 	}
diff --git a/arch/arm/mach-msm/qdsp5/audmgr.h b/arch/arm/mach-msm/qdsp5/audmgr.h
index 225beef..34c8488 100644
--- a/arch/arm/mach-msm/qdsp5/audmgr.h
+++ b/arch/arm/mach-msm/qdsp5/audmgr.h
@@ -1,7 +1,7 @@
 /* arch/arm/mach-msm/qdsp5/audmgr.h
  *
  * Copyright (C) 2008 Google, Inc.
- * Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -253,6 +253,20 @@
 			audpp_cmd_cfg_object_params_eqalizer *eq);
 int audpp_dsp_set_rx_iir(unsigned id, unsigned enable,
 				audpp_cmd_cfg_object_params_pcm *iir);
+
+int audpp_dsp_set_rx_srs_trumedia_g
+	(struct audpp_cmd_cfg_object_params_srstm_g *srstm);
+int audpp_dsp_set_rx_srs_trumedia_w
+	(struct audpp_cmd_cfg_object_params_srstm_w *srstm);
+int audpp_dsp_set_rx_srs_trumedia_c
+	(struct audpp_cmd_cfg_object_params_srstm_c *srstm);
+int audpp_dsp_set_rx_srs_trumedia_h
+	(struct audpp_cmd_cfg_object_params_srstm_h *srstm);
+int audpp_dsp_set_rx_srs_trumedia_p
+	(struct audpp_cmd_cfg_object_params_srstm_p *srstm);
+int audpp_dsp_set_rx_srs_trumedia_l
+	(struct audpp_cmd_cfg_object_params_srstm_l *srstm);
+
 int audpp_dsp_set_vol_pan(unsigned id,
 				audpp_cmd_cfg_object_params_volume *vol_pan);
 int audpp_dsp_set_qconcert_plus(unsigned id, unsigned enable,
diff --git a/arch/arm/mach-msm/qdsp5/audpp.c b/arch/arm/mach-msm/qdsp5/audpp.c
index 2dbb5dc0..1616ad0 100644
--- a/arch/arm/mach-msm/qdsp5/audpp.c
+++ b/arch/arm/mach-msm/qdsp5/audpp.c
@@ -71,6 +71,14 @@
 #define AUDPP_CLNT_MAX_COUNT 6
 #define AUDPP_AVSYNC_INFO_SIZE 7
 
+#define AUDPP_SRS_PARAMS 2
+#define AUDPP_SRS_PARAMS_G 0
+#define AUDPP_SRS_PARAMS_W 1
+#define AUDPP_SRS_PARAMS_C 2
+#define AUDPP_SRS_PARAMS_H 3
+#define AUDPP_SRS_PARAMS_P 4
+#define AUDPP_SRS_PARAMS_L 5
+
 #define AUDPP_CMD_CFG_OBJ_UPDATE 0x8000
 #define AUDPP_CMD_EQ_FLAG_DIS	0x0000
 #define AUDPP_CMD_EQ_FLAG_ENA	-1
@@ -604,6 +612,108 @@
 }
 EXPORT_SYMBOL(audpp_dsp_set_rx_iir);
 
+int audpp_dsp_set_rx_srs_trumedia_g(
+	struct audpp_cmd_cfg_object_params_srstm_g *srstm)
+{
+	struct audpp_cmd_cfg_object_params_srstm_g cmd;
+
+	MM_DBG("%s\n", __func__);
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.common.cmd_id = AUDPP_SRS_PARAMS;
+	cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE;
+	cmd.common.command_type = AUDPP_SRS_PARAMS_G;
+
+	memcpy(cmd.v, srstm->v, sizeof(srstm->v));
+
+	return audpp_send_queue3(&cmd, sizeof(cmd));
+}
+EXPORT_SYMBOL(audpp_dsp_set_rx_srs_trumedia_g);
+
+int audpp_dsp_set_rx_srs_trumedia_w(
+	struct audpp_cmd_cfg_object_params_srstm_w *srstm)
+{
+	struct audpp_cmd_cfg_object_params_srstm_w cmd;
+
+	MM_DBG("%s\n", __func__);
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.common.cmd_id = AUDPP_SRS_PARAMS;
+	cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE;
+	cmd.common.command_type = AUDPP_SRS_PARAMS_W;
+
+	memcpy(cmd.v, srstm->v, sizeof(srstm->v));
+
+	return audpp_send_queue3(&cmd, sizeof(cmd));
+}
+EXPORT_SYMBOL(audpp_dsp_set_rx_srs_trumedia_w);
+
+int audpp_dsp_set_rx_srs_trumedia_c(
+	struct audpp_cmd_cfg_object_params_srstm_c *srstm)
+{
+	struct audpp_cmd_cfg_object_params_srstm_c cmd;
+
+	MM_DBG("%s\n", __func__);
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.common.cmd_id = AUDPP_SRS_PARAMS;
+	cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE;
+	cmd.common.command_type = AUDPP_SRS_PARAMS_C;
+
+	memcpy(cmd.v, srstm->v, sizeof(srstm->v));
+
+	return audpp_send_queue3(&cmd, sizeof(cmd));
+}
+EXPORT_SYMBOL(audpp_dsp_set_rx_srs_trumedia_c);
+
+int audpp_dsp_set_rx_srs_trumedia_h(
+	struct audpp_cmd_cfg_object_params_srstm_h *srstm)
+{
+	struct audpp_cmd_cfg_object_params_srstm_h cmd;
+
+	MM_DBG("%s\n", __func__);
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.common.cmd_id = AUDPP_SRS_PARAMS;
+	cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE;
+	cmd.common.command_type = AUDPP_SRS_PARAMS_H;
+
+	memcpy(cmd.v, srstm->v, sizeof(srstm->v));
+
+	return audpp_send_queue3(&cmd, sizeof(cmd));
+}
+EXPORT_SYMBOL(audpp_dsp_set_rx_srs_trumedia_h);
+
+int audpp_dsp_set_rx_srs_trumedia_p(
+	struct audpp_cmd_cfg_object_params_srstm_p *srstm)
+{
+	struct audpp_cmd_cfg_object_params_srstm_p cmd;
+
+	MM_DBG("%s\n", __func__);
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.common.cmd_id = AUDPP_SRS_PARAMS;
+	cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE;
+	cmd.common.command_type = AUDPP_SRS_PARAMS_P;
+
+	memcpy(cmd.v, srstm->v, sizeof(srstm->v));
+
+	return audpp_send_queue3(&cmd, sizeof(cmd));
+}
+EXPORT_SYMBOL(audpp_dsp_set_rx_srs_trumedia_p);
+
+int audpp_dsp_set_rx_srs_trumedia_l(
+	struct audpp_cmd_cfg_object_params_srstm_l *srstm)
+{
+	struct audpp_cmd_cfg_object_params_srstm_l cmd;
+
+	MM_DBG("%s\n", __func__);
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.common.cmd_id = AUDPP_SRS_PARAMS;
+	cmd.common.comman_cfg = AUDPP_CMD_CFG_OBJ_UPDATE;
+	cmd.common.command_type = AUDPP_SRS_PARAMS_L;
+
+	memcpy(cmd.v, srstm->v, sizeof(srstm->v));
+
+	return audpp_send_queue3(&cmd, sizeof(cmd));
+}
+EXPORT_SYMBOL(audpp_dsp_set_rx_srs_trumedia_l);
+
 /* Implementation Of COPP + POPP */
 int audpp_dsp_set_eq(unsigned id, unsigned enable,
 		     audpp_cmd_cfg_object_params_eqalizer *eq)
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_lpa.c b/arch/arm/mach-msm/qdsp5v2/audio_lpa.c
index d43c961..c8f0590 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_lpa.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_lpa.c
@@ -559,6 +559,8 @@
 
 			if ((signed)(temp >= 0) &&
 			((signed)(next_buf->buf.data_len - temp) >= 0)) {
+				MM_DBG("audlpa_async_send_buffer - sending the"
+					"rest of the buffer bassedon AV sync");
 				cmd.buf_ptr	= (unsigned) (next_buf->paddr +
 						  (next_buf->buf.data_len -
 						   temp));
@@ -570,6 +572,21 @@
 				audplay_send_queue0(audio, &cmd, sizeof(cmd));
 				audio->out_needed = 0;
 				audio->drv_status |= ADRV_STATUS_OBUF_GIVEN;
+			} else if ((signed)(temp >= 0) &&
+				((signed)(next_buf->buf.data_len -
+							temp) < 0)) {
+				MM_DBG("audlpa_async_send_buffer - else case:"
+					"sending the rest of the buffer bassedon"
+					"AV sync");
+				cmd.buf_ptr	= (unsigned) next_buf->paddr;
+				cmd.buf_size = next_buf->buf.data_len >> 1;
+				cmd.partition_number	= 0;
+				audio->bytecount_given = audio->bytecount_head +
+					next_buf->buf.data_len;
+				wmb();
+				audplay_send_queue0(audio, &cmd, sizeof(cmd));
+				audio->out_needed = 0;
+				audio->drv_status |= ADRV_STATUS_OBUF_GIVEN;
 			}
 		}
 	}
@@ -606,15 +623,19 @@
 			temp = audio->bytecount_head;
 			used_buf = list_first_entry(&audio->out_queue,
 					struct audlpa_buffer_node, list);
-
-			audio->bytecount_head += used_buf->buf.data_len;
-			temp = audio->bytecount_head;
-			list_del(&used_buf->list);
-			evt_payload.aio_buf = used_buf->buf;
-			audlpa_post_event(audio, AUDIO_EVENT_WRITE_DONE,
-					  evt_payload);
-			kfree(used_buf);
-			audio->drv_status &= ~ADRV_STATUS_OBUF_GIVEN;
+			if (audio->device_switch !=
+				DEVICE_SWITCH_STATE_COMPLETE) {
+				audio->bytecount_head +=
+						used_buf->buf.data_len;
+				temp = audio->bytecount_head;
+				list_del(&used_buf->list);
+				evt_payload.aio_buf = used_buf->buf;
+				audlpa_post_event(audio,
+						AUDIO_EVENT_WRITE_DONE,
+						  evt_payload);
+				kfree(used_buf);
+				audio->drv_status &= ~ADRV_STATUS_OBUF_GIVEN;
+			}
 		}
 	}
 	if (audio->out_needed) {
@@ -1150,6 +1171,15 @@
 		audio->wflush = 1;
 		audio_ioport_reset(audio);
 		if (audio->running) {
+			if (!(audio->drv_status & ADRV_STATUS_PAUSE)) {
+				rc = audpp_pause(audio->dec_id, (int) arg);
+				if (rc < 0) {
+					MM_ERR("%s: pause cmd failed rc=%d\n",
+						__func__, rc);
+					rc = -EINTR;
+					break;
+				}
+			}
 			audpp_flush(audio->dec_id);
 			rc = wait_event_interruptible(audio->write_wait,
 				!audio->wflush);
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 521564a..3db397b 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -160,11 +160,11 @@
 		"a225_pm4.fw", "a225_pfp.fw", &adreno_a2xx_gpudev,
 		1536, 768, 3, SZ_512K },
 	/* A3XX doesn't use the pix_shader_start */
-	{ ADRENO_REV_A305, 3, 1, ANY_ID, ANY_ID,
+	{ ADRENO_REV_A305, 3, 0, 5, 0,
 		"a300_pm4.fw", "a300_pfp.fw", &adreno_a3xx_gpudev,
 		512, 0, 2, SZ_256K },
 	/* A3XX doesn't use the pix_shader_start */
-	{ ADRENO_REV_A320, 3, 1, ANY_ID, ANY_ID,
+	{ ADRENO_REV_A320, 3, 2, 0, 0,
 		"a300_pm4.fw", "a300_pfp.fw", &adreno_a3xx_gpudev,
 		512, 0, 2, SZ_512K },
 
@@ -358,26 +358,29 @@
 static unsigned int
 a3xx_getchipid(struct kgsl_device *device)
 {
-	unsigned int chipid = 0;
-	unsigned int coreid, majorid, minorid, patchid;
-	unsigned int version;
+	unsigned int majorid, minorid, patchid;
 
-	adreno_regread(device, A3XX_RBBM_HW_VERSION, &version);
+	/*
+	 * We could detect the chipID from the hardware but it takes multiple
+	 * registers to find the right combination. Since we traffic exclusively
+	 * in system on chips, we can be (mostly) confident that a SOC version
+	 * will match a GPU (at this juncture at least).  So do the lazy/quick
+	 * thing and set the chip_id based on the SoC
+	 */
 
-	coreid = 0x03;
+	if (cpu_is_apq8064()) {
+		/* A320 */
+		majorid = 2;
+		minorid = 0;
+		patchid = 0;
+	} else if (cpu_is_msm8930()) {
+		/* A305 */
+		majorid = 0;
+		minorid = 5;
+		patchid = 0;
+	}
 
-	/* Version might not be set - if it isn't, assume this is 320 */
-	if (version)
-		majorid = version & 0x0F;
-	else
-		majorid = 1;
-
-	minorid = (version >> 4) & 0xFFF;
-	patchid = 0;
-
-	chipid = (coreid << 24) | (majorid << 16) | (minorid << 8) | patchid;
-
-	return chipid;
+	return (0x03 << 24) | (majorid << 16) | (minorid << 8) | patchid;
 }
 
 static unsigned int
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index b7e0e57..e08088d 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -35,6 +35,8 @@
 
 #ifdef CONFIG_MSM_SCM
 #define ADRENO_DEFAULT_PWRSCALE_POLICY  (&kgsl_pwrscale_policy_tz)
+#elif defined CONFIG_MSM_SLEEP_STATS_DEVICE
+#define ADRENO_DEFAULT_PWRSCALE_POLICY  (&kgsl_pwrscale_policy_idlestats)
 #else
 #define ADRENO_DEFAULT_PWRSCALE_POLICY  NULL
 #endif
diff --git a/drivers/gpu/msm/adreno_postmortem.c b/drivers/gpu/msm/adreno_postmortem.c
index e4bc470..5b197b4 100644
--- a/drivers/gpu/msm/adreno_postmortem.c
+++ b/drivers/gpu/msm/adreno_postmortem.c
@@ -665,7 +665,8 @@
 		"        MPU_END    = %08X | VA_RANGE = %08X | PT_BASE  ="
 		" %08X\n", r1, r2, r3);
 
-	KGSL_LOG_DUMP(device, "PAGETABLE SIZE: %08X ", KGSL_PAGETABLE_SIZE);
+	KGSL_LOG_DUMP(device, "PAGETABLE SIZE: %08X ",
+		kgsl_mmu_get_ptsize());
 
 	kgsl_regread(device, MH_MMU_TRAN_ERROR, &r1);
 	KGSL_LOG_DUMP(device, "        TRAN_ERROR = %08X\n", r1);
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 5464bbb..37d18bc 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -559,8 +559,8 @@
 					struct kgsl_device, display_off);
 	KGSL_PWR_WARN(device, "late resume start\n");
 	mutex_lock(&device->mutex);
-	kgsl_pwrctrl_wake(device);
 	device->pwrctrl.restore_slumber = 0;
+	kgsl_pwrctrl_wake(device);
 	kgsl_pwrctrl_pwrlevel_change(device, KGSL_PWRLEVEL_TURBO);
 	mutex_unlock(&device->mutex);
 	kgsl_check_idle(device);
@@ -2416,8 +2416,8 @@
 static int __devinit
 kgsl_ptdata_init(void)
 {
-	kgsl_driver.ptpool = kgsl_mmu_ptpool_init(KGSL_PAGETABLE_SIZE,
-						kgsl_pagetable_count);
+	kgsl_driver.ptpool = kgsl_mmu_ptpool_init(kgsl_pagetable_count);
+
 	if (!kgsl_driver.ptpool)
 		return -ENOMEM;
 	return 0;
diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h
index 06f78fc..20ed808 100644
--- a/drivers/gpu/msm/kgsl.h
+++ b/drivers/gpu/msm/kgsl.h
@@ -40,10 +40,6 @@
 #define KGSL_PAGETABLE_ENTRIES(_sz) (((_sz) >> PAGE_SHIFT) + \
 				     KGSL_PT_EXTRA_ENTRIES)
 
-#define KGSL_PAGETABLE_SIZE \
-ALIGN(KGSL_PAGETABLE_ENTRIES(CONFIG_MSM_KGSL_PAGE_TABLE_SIZE) * \
-KGSL_PAGETABLE_ENTRY_SIZE, PAGE_SIZE)
-
 #ifdef CONFIG_KGSL_PER_PROCESS_PAGE_TABLE
 #define KGSL_PAGETABLE_COUNT (CONFIG_MSM_KGSL_PAGE_TABLE_COUNT)
 #else
diff --git a/drivers/gpu/msm/kgsl_cffdump.c b/drivers/gpu/msm/kgsl_cffdump.c
index e9455cb..a972f69 100644
--- a/drivers/gpu/msm/kgsl_cffdump.c
+++ b/drivers/gpu/msm/kgsl_cffdump.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, 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
@@ -359,7 +359,7 @@
 void kgsl_cffdump_open(enum kgsl_deviceid device_id)
 {
 	kgsl_cffdump_memory_base(device_id, KGSL_PAGETABLE_BASE,
-			CONFIG_MSM_KGSL_PAGE_TABLE_SIZE, SZ_256K);
+			kgsl_mmu_get_ptsize(), SZ_256K);
 }
 
 void kgsl_cffdump_memory_base(enum kgsl_deviceid device_id, unsigned int base,
diff --git a/drivers/gpu/msm/kgsl_gpummu.c b/drivers/gpu/msm/kgsl_gpummu.c
index 98216f8..942aa12 100644
--- a/drivers/gpu/msm/kgsl_gpummu.c
+++ b/drivers/gpu/msm/kgsl_gpummu.c
@@ -22,6 +22,10 @@
 #include "kgsl_device.h"
 #include "kgsl_sharedmem.h"
 
+#define KGSL_PAGETABLE_SIZE \
+	ALIGN(KGSL_PAGETABLE_ENTRIES(CONFIG_MSM_KGSL_PAGE_TABLE_SIZE) * \
+	KGSL_PAGETABLE_ENTRY_SIZE, PAGE_SIZE)
+
 static ssize_t
 sysfs_show_ptpool_entries(struct kobject *kobj,
 			  struct kobj_attribute *attr,
@@ -310,16 +314,15 @@
 /**
  * kgsl_ptpool_init
  * @pool:  A pointer to a ptpool structure to initialize
- * @ptsize: The size of each pagetable entry
  * @entries:  The number of inital entries to add to the pool
  *
  * Initalize a pool and allocate an initial chunk of entries.
  */
-void *kgsl_gpummu_ptpool_init(int ptsize, int entries)
+void *kgsl_gpummu_ptpool_init(int entries)
 {
+	int ptsize = KGSL_PAGETABLE_SIZE;
 	struct kgsl_ptpool *pool;
 	int ret = 0;
-	BUG_ON(ptsize == 0);
 
 	pool = kzalloc(sizeof(struct kgsl_ptpool), GFP_KERNEL);
 	if (!pool) {
diff --git a/drivers/gpu/msm/kgsl_gpummu.h b/drivers/gpu/msm/kgsl_gpummu.h
index 46466a8..cac6930 100644
--- a/drivers/gpu/msm/kgsl_gpummu.h
+++ b/drivers/gpu/msm/kgsl_gpummu.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, 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
@@ -73,8 +73,7 @@
 	int chunks;
 };
 
-void *kgsl_gpummu_ptpool_init(int ptsize,
-			int entries);
+void *kgsl_gpummu_ptpool_init(int entries);
 void kgsl_gpummu_ptpool_destroy(void *ptpool);
 
 static inline unsigned int kgsl_pt_get_base_addr(struct kgsl_pagetable *pt)
diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c
index 319addb..ceb3212 100644
--- a/drivers/gpu/msm/kgsl_mmu.c
+++ b/drivers/gpu/msm/kgsl_mmu.c
@@ -148,9 +148,10 @@
 
 	pt = _get_pt_from_kobj(kobj);
 
-	if (pt)
+	if (pt) {
 		ret += snprintf(buf, PAGE_SIZE, "0x%x\n",
-			CONFIG_MSM_KGSL_PAGE_TABLE_SIZE);
+			kgsl_mmu_get_ptsize());
+	}
 
 	kgsl_put_pagetable(pt);
 	return ret;
@@ -268,6 +269,22 @@
 	return ret;
 }
 
+unsigned int kgsl_mmu_get_ptsize(void)
+{
+	/*
+	 * For IOMMU, we could do up to 4G virtual range if we wanted to, but
+	 * it makes more sense to return a smaller range and leave the rest of
+	 * the virtual range for future improvements
+	 */
+
+	if (KGSL_MMU_TYPE_GPU == kgsl_mmu_type)
+		return CONFIG_MSM_KGSL_PAGE_TABLE_SIZE;
+	else if (KGSL_MMU_TYPE_IOMMU == kgsl_mmu_type)
+		return SZ_2G;
+	else
+		return 0;
+}
+
 unsigned int kgsl_mmu_get_current_ptbase(struct kgsl_device *device)
 {
 	struct kgsl_mmu *mmu = &device->mmu;
@@ -392,6 +409,7 @@
 	int status = 0;
 	struct kgsl_pagetable *pagetable = NULL;
 	unsigned long flags;
+	unsigned int ptsize;
 
 	pagetable = kzalloc(sizeof(struct kgsl_pagetable), GFP_KERNEL);
 	if (pagetable == NULL) {
@@ -403,9 +421,11 @@
 	kref_init(&pagetable->refcount);
 
 	spin_lock_init(&pagetable->lock);
+
+	ptsize = kgsl_mmu_get_ptsize();
+
 	pagetable->name = name;
-	pagetable->max_entries = KGSL_PAGETABLE_ENTRIES(
-					CONFIG_MSM_KGSL_PAGE_TABLE_SIZE);
+	pagetable->max_entries = KGSL_PAGETABLE_ENTRIES(ptsize);
 
 	pagetable->pool = gen_pool_create(PAGE_SHIFT, -1);
 	if (pagetable->pool == NULL) {
@@ -414,7 +434,7 @@
 	}
 
 	if (gen_pool_add(pagetable->pool, KGSL_PAGETABLE_BASE,
-				CONFIG_MSM_KGSL_PAGE_TABLE_SIZE, -1)) {
+				ptsize, -1)) {
 		KGSL_CORE_ERR("gen_pool_add failed\n");
 		goto err_pool;
 	}
@@ -697,10 +717,10 @@
 }
 EXPORT_SYMBOL(kgsl_mmu_ptpool_destroy);
 
-void *kgsl_mmu_ptpool_init(int ptsize, int entries)
+void *kgsl_mmu_ptpool_init(int entries)
 {
 	if (KGSL_MMU_TYPE_GPU == kgsl_mmu_type)
-		return kgsl_gpummu_ptpool_init(ptsize, entries);
+		return kgsl_gpummu_ptpool_init(entries);
 	else
 		return (void *)(-1);
 }
diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h
index 1338d0d..0ff5881 100644
--- a/drivers/gpu/msm/kgsl_mmu.h
+++ b/drivers/gpu/msm/kgsl_mmu.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-2012, 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
@@ -175,13 +175,13 @@
 int kgsl_mmu_get_ptname_from_ptbase(unsigned int pt_base);
 int kgsl_mmu_pt_get_flags(struct kgsl_pagetable *pt,
 			enum kgsl_deviceid id);
-
 void kgsl_mmu_ptpool_destroy(void *ptpool);
-void *kgsl_mmu_ptpool_init(int ptsize, int entries);
+void *kgsl_mmu_ptpool_init(int entries);
 int kgsl_mmu_enabled(void);
 int kgsl_mmu_pt_equal(struct kgsl_pagetable *pt,
 			unsigned int pt_base);
 void kgsl_mmu_set_mmutype(char *mmutype);
 unsigned int kgsl_mmu_get_current_ptbase(struct kgsl_device *device);
 enum kgsl_mmutype kgsl_mmu_get_mmutype(void);
+unsigned int kgsl_mmu_get_ptsize(void);
 #endif /* __KGSL_MMU_H */
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 406d0c9..a03e530 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -773,13 +773,15 @@
 	case KGSL_STATE_SLEEP:
 		del_timer_sync(&device->idle_timer);
 		kgsl_pwrctrl_pwrlevel_change(device, KGSL_PWRLEVEL_NOMINAL);
+		device->pwrctrl.restore_slumber = true;
 		device->ftbl->suspend_context(device);
 		device->ftbl->stop(device);
-		device->pwrctrl.restore_slumber = true;
 		_sleep_accounting(device);
 		kgsl_pwrctrl_set_state(device, KGSL_STATE_SLUMBER);
 		if (device->idle_wakelock.name)
 			wake_unlock(&device->idle_wakelock);
+		pm_qos_update_request(&device->pm_qos_req_dma,
+						PM_QOS_DEFAULT_VALUE);
 		break;
 	case KGSL_STATE_SLUMBER:
 		break;
@@ -849,8 +851,9 @@
 		mod_timer(&device->idle_timer,
 				jiffies + device->pwrctrl.interval_timeout);
 		wake_lock(&device->idle_wakelock);
-		pm_qos_update_request(&device->pm_qos_req_dma,
-				GPU_SWFI_LATENCY);
+		if (device->pwrctrl.restore_slumber == false)
+			pm_qos_update_request(&device->pm_qos_req_dma,
+						GPU_SWFI_LATENCY);
 	case KGSL_STATE_ACTIVE:
 		break;
 	default:
diff --git a/drivers/media/video/msm/wfd/vsg-subdev.c b/drivers/media/video/msm/wfd/vsg-subdev.c
index 8e385a4..7f5a4ad 100644
--- a/drivers/media/video/msm/wfd/vsg-subdev.c
+++ b/drivers/media/video/msm/wfd/vsg-subdev.c
@@ -119,8 +119,8 @@
 	INIT_LIST_HEAD(&buf_info->node);
 
 	ktime_get_ts(&buf_info->time);
-	mod_timer(&context->threshold_timer, jiffies +
-			nsecs_to_jiffies(context->max_frame_interval));
+	hrtimer_forward_now(&context->threshold_timer, ns_to_ktime(
+				context->max_frame_interval));
 
 	list_for_each_entry(temp, &context->busy_queue.node, node) {
 		if (mdp_buf_info_equals(&temp->mdp_buf_info,
@@ -250,11 +250,14 @@
 	kfree(work);
 }
 
-static void vsg_threshold_timeout_func(unsigned long data)
+static enum hrtimer_restart vsg_threshold_timeout_func(struct hrtimer *timer)
 {
-	struct vsg_context *context = (struct vsg_context *)data;
-	struct vsg_work *task = kzalloc(sizeof(*task), GFP_ATOMIC);
+	struct vsg_context *context = NULL;
+	struct vsg_work *task = NULL;
 
+	task = kzalloc(sizeof(*task), GFP_ATOMIC);
+	context = container_of(timer, struct vsg_context,
+			threshold_timer);
 	if (!task) {
 		WFD_MSG_ERR("Out of memory in %s", __func__);
 		goto threshold_err_bad_param;
@@ -263,15 +266,14 @@
 		goto threshold_err_bad_param;
 	}
 
-	mod_timer(&context->threshold_timer, jiffies +
-			nsecs_to_jiffies(context->max_frame_interval));
-
 	INIT_WORK(&task->work, vsg_timer_helper_func);
 	task->context = context;
 
 	queue_work(context->work_queue, &task->work);
 threshold_err_bad_param:
-	return;
+	hrtimer_forward_now(&context->threshold_timer, ns_to_ktime(
+				context->max_frame_interval));
+	return HRTIMER_RESTART;
 }
 
 int vsg_init(struct v4l2_subdev *sd, u32 val)
@@ -296,10 +298,9 @@
 	context->frame_interval = DEFAULT_FRAME_INTERVAL;
 	context->max_frame_interval = DEFAULT_MAX_FRAME_INTERVAL;
 
-	context->threshold_timer = (struct timer_list)
-		TIMER_INITIALIZER(vsg_threshold_timeout_func,
-				context->max_frame_interval,
-				(unsigned long)context);
+	hrtimer_init(&context->threshold_timer, CLOCK_MONOTONIC,
+			HRTIMER_MODE_REL);
+	context->threshold_timer.function = vsg_threshold_timeout_func;
 
 	context->last_buffer = context->regen_buffer = NULL;
 	context->send_regen_buffer = false;
@@ -345,8 +346,8 @@
 	}
 
 	context->state = VSG_STATE_STARTED;
-	mod_timer(&context->threshold_timer, jiffies +
-			nsecs_to_jiffies(context->max_frame_interval));
+	hrtimer_start(&context->threshold_timer, ns_to_ktime(context->
+			max_frame_interval), HRTIMER_MODE_REL);
 	return 0;
 }
 
@@ -373,7 +374,7 @@
 		}
 	}
 
-	del_timer_sync(&context->threshold_timer);
+	hrtimer_cancel(&context->threshold_timer);
 
 	mutex_unlock(&context->mutex);
 
diff --git a/drivers/media/video/msm/wfd/vsg-subdev.h b/drivers/media/video/msm/wfd/vsg-subdev.h
index 826105c..f0e16633 100644
--- a/drivers/media/video/msm/wfd/vsg-subdev.h
+++ b/drivers/media/video/msm/wfd/vsg-subdev.h
@@ -61,7 +61,7 @@
 	/* All time related values below in nanosecs */
 	int64_t frame_interval, max_frame_interval;
 	struct workqueue_struct *work_queue;
-	struct timer_list threshold_timer;
+	struct hrtimer threshold_timer;
 	struct mutex mutex;
 	struct vsg_buf_info *last_buffer, *regen_buffer;
 	bool send_regen_buffer;
diff --git a/drivers/platform/msm/sps/sps_bam.c b/drivers/platform/msm/sps/sps_bam.c
index e48f59b..b5192d1 100644
--- a/drivers/platform/msm/sps/sps_bam.c
+++ b/drivers/platform/msm/sps/sps_bam.c
@@ -802,13 +802,13 @@
 	if (dev->pipes[pipe_index] != BAM_PIPE_UNASSIGNED) {
 		SPS_ERR("sps:Invalid pipe %d on BAM 0x%x for connect",
 			pipe_index, BAM_ID(dev));
-		goto exit_err;
+		return SPS_ERROR;
 	}
 
 	if (bam_pipe_is_enabled(dev->base, pipe_index)) {
 		SPS_ERR("sps:BAM 0x%x pipe %d sharing violation",
 			BAM_ID(dev), pipe_index);
-		goto exit_err;
+		return SPS_ERROR;
 	}
 
 	if (bam_pipe_init(dev->base, pipe_index, &hw_params, dev->props.ee)) {
diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c
index 6caa48f..053b81f 100644
--- a/drivers/platform/msm/usb_bam.c
+++ b/drivers/platform/msm/usb_bam.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, 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
@@ -39,6 +39,11 @@
 
 static struct usb_bam_connect_info usb_bam_connections[CONNECTIONS_NUM];
 
+static inline int bam_offset(struct msm_usb_bam_platform_data *pdata)
+{
+	return pdata->usb_active_bam * CONNECTIONS_NUM * 2;
+}
+
 static int connect_pipe(u8 connection_idx, enum usb_bam_pipe_dir pipe_dir,
 						u8 *usb_pipe_idx)
 {
@@ -51,7 +56,7 @@
 			(usb_bam_pdev->dev.platform_data);
 	struct usb_bam_pipe_connect *pipe_connection =
 			(struct usb_bam_pipe_connect *)(pdata->connections +
-						(2*connection_idx+pipe_dir));
+			 bam_offset(pdata) + (2*connection_idx+pipe_dir));
 
 	pipe = sps_alloc_endpoint();
 	if (pipe == NULL) {
@@ -162,6 +167,7 @@
 
 	return 0;
 }
+
 static int usb_bam_init(void)
 {
 	u32 h_usb;
@@ -207,6 +213,62 @@
 	return 0;
 }
 
+static char *bam_enable_strings[2] = {
+	[HSUSB_BAM] = "hsusb",
+	[HSIC_BAM]  = "hsic",
+};
+
+static ssize_t
+usb_bam_show_enable(struct device *dev, struct device_attribute *attr,
+		    char *buf)
+{
+	struct platform_device *pdev = container_of(dev, struct platform_device,
+						    dev);
+	struct msm_usb_bam_platform_data *pdata =
+		(struct msm_usb_bam_platform_data *)
+			(usb_bam_pdev->dev.platform_data);
+
+	if (!pdev || !pdata)
+		return 0;
+	return scnprintf(buf, PAGE_SIZE, "%s\n",
+			 bam_enable_strings[pdata->usb_active_bam]);
+}
+
+static ssize_t usb_bam_store_enable(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	struct platform_device *pdev = container_of(dev, struct platform_device,
+						    dev);
+	struct msm_usb_bam_platform_data *pdata =
+		(struct msm_usb_bam_platform_data *)
+			(usb_bam_pdev->dev.platform_data);
+	char str[10], *pstr;
+	int ret, i;
+
+	strlcpy(str, buf, sizeof(str));
+	pstr = strim(str);
+
+	for (i = 0; i < ARRAY_SIZE(bam_enable_strings); i++) {
+		if (!strncmp(pstr, bam_enable_strings[i], sizeof(str)))
+			pdata->usb_active_bam = i;
+	}
+
+	dev_dbg(&pdev->dev, "active_bam=%s\n",
+		bam_enable_strings[pdata->usb_active_bam]);
+
+	ret = usb_bam_init();
+	if (ret) {
+		dev_err(&pdev->dev, "failed to initialize usb bam\n");
+		return ret;
+	}
+
+	return count;
+}
+
+static DEVICE_ATTR(enable, S_IWUSR | S_IRUSR, usb_bam_show_enable,
+		   usb_bam_store_enable);
+
 static int usb_bam_probe(struct platform_device *pdev)
 {
 	int ret, i;
@@ -222,13 +284,11 @@
 	}
 	usb_bam_pdev = pdev;
 
-	ret = usb_bam_init();
-	if (ret) {
-		dev_err(&pdev->dev, "failed to initialize usb bam\n");
-		return ret;
-	}
+	ret = device_create_file(&pdev->dev, &dev_attr_enable);
+	if (ret)
+		dev_err(&pdev->dev, "failed to create device file\n");
 
-	return 0;
+	return ret;
 }
 
 static struct platform_driver usb_bam_driver = {
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index 2d43a78..9d1cef7 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -83,7 +83,7 @@
 	if (!init)
 		goto disable_reg;
 
-	mehci->hsic_vddcx = regulator_get(mehci->dev, "HSIC_VDDCX");
+	mehci->hsic_vddcx = devm_regulator_get(mehci->dev, "HSIC_VDDCX");
 	if (IS_ERR(mehci->hsic_vddcx)) {
 		dev_err(mehci->dev, "unable to get hsic vddcx\n");
 		return PTR_ERR(mehci->hsic_vddcx);
@@ -95,7 +95,7 @@
 	if (ret) {
 		dev_err(mehci->dev, "unable to set the voltage"
 				"for hsic vddcx\n");
-		goto reg_set_voltage_err;
+		return ret;
 	}
 
 	ret = regulator_set_optimum_mode(mehci->hsic_vddcx,
@@ -121,9 +121,6 @@
 reg_optimum_mode_err:
 	regulator_set_voltage(mehci->hsic_vddcx, 0,
 				USB_PHY_VDD_DIG_VOL_MIN);
-reg_set_voltage_err:
-	regulator_put(mehci->hsic_vddcx);
-
 	return ret;
 
 }
@@ -170,7 +167,7 @@
 	if (!init)
 		goto disable_reg;
 
-	hsic_hub_reg = regulator_get(mehci->dev, "EXT_HUB_VDDIO");
+	hsic_hub_reg = devm_regulator_get(mehci->dev, "EXT_HUB_VDDIO");
 	if (IS_ERR(hsic_hub_reg)) {
 		dev_err(mehci->dev, "unable to get ext hub vddcx\n");
 		return PTR_ERR(hsic_hub_reg);
@@ -180,7 +177,7 @@
 	if (ret < 0) {
 		dev_err(mehci->dev, "gpio request failed for GPIO%d\n",
 							pdata->hub_reset);
-		goto gpio_req_fail;
+		return ret;
 	}
 
 	ret = regulator_set_voltage(hsic_hub_reg,
@@ -222,8 +219,6 @@
 				HSIC_HUB_VDD_VOL_MIN);
 reg_set_voltage_fail:
 	gpio_free(pdata->hub_reset);
-gpio_req_fail:
-	regulator_put(hsic_hub_reg);
 
 	return ret;
 
diff --git a/drivers/video/msm/mddi_orise.c b/drivers/video/msm/mddi_orise.c
index dc913e6..fa48c75 100644
--- a/drivers/video/msm/mddi_orise.c
+++ b/drivers/video/msm/mddi_orise.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, 2012 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
@@ -102,6 +102,7 @@
 		MSM_FB_SINGLE_MODE_PANEL(pinfo);
 		pinfo->type = MDDI_PANEL;
 		pinfo->pdest = DISPLAY_1;
+		pinfo->mddi.is_type1 = TRUE;
 		pinfo->mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
 		pinfo->wait_cycle = 0;
 		pinfo->bpp = 18;
diff --git a/drivers/video/msm/mddi_prism.c b/drivers/video/msm/mddi_prism.c
index 5269b22..ec2bf57 100644
--- a/drivers/video/msm/mddi_prism.c
+++ b/drivers/video/msm/mddi_prism.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2010, 2012 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
@@ -87,6 +87,7 @@
 		pinfo->pdest = DISPLAY_1;
 		pinfo->mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
 		pinfo->wait_cycle = 0;
+		pinfo->mddi.is_type1 = TRUE;
 		pinfo->bpp = 18;
 		pinfo->fb_num = 2;
 		pinfo->clk_rate = 153600000;
diff --git a/drivers/video/msm/mddi_quickvx.c b/drivers/video/msm/mddi_quickvx.c
index 330e679..95e7d41 100644
--- a/drivers/video/msm/mddi_quickvx.c
+++ b/drivers/video/msm/mddi_quickvx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, 2012 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
@@ -695,6 +695,7 @@
 		pinfo->lcd.vsync_enable = TRUE;
 		pinfo->lcd.refx100 = (mddi_quickvx_rows_per_second \
 			* 100)/mddi_quickvx_rows_per_refresh;
+		pinfo->mddi.is_type1 = TRUE;
 		pinfo->lcd.v_back_porch = 4;
 		pinfo->lcd.v_front_porch = 2;
 		pinfo->lcd.v_pulse_width = 2;
diff --git a/drivers/video/msm/mddi_sharp.c b/drivers/video/msm/mddi_sharp.c
index b2a7188..6a9008f 100644
--- a/drivers/video/msm/mddi_sharp.c
+++ b/drivers/video/msm/mddi_sharp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2010, 2012 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
@@ -855,6 +855,7 @@
 		pinfo->clk_min = 120000000;
 		pinfo->clk_max = 125000000;
 		pinfo->lcd.vsync_enable = TRUE;
+		pinfo->mddi.is_type1 = TRUE;
 		pinfo->lcd.refx100 =
 			(mddi_sharp_rows_per_second * 100) /
 			mddi_sharp_rows_per_refresh;
diff --git a/drivers/video/msm/mddi_toshiba_vga.c b/drivers/video/msm/mddi_toshiba_vga.c
index 794edff..73749f9 100644
--- a/drivers/video/msm/mddi_toshiba_vga.c
+++ b/drivers/video/msm/mddi_toshiba_vga.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, 2012 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
@@ -90,6 +90,7 @@
 	pinfo.wait_cycle = 0;
 	pinfo.bpp = 18;
 	pinfo.lcd.vsync_enable = TRUE;
+	pinfo.mddi.is_type1 = TRUE;
 	pinfo.lcd.refx100 = 6118;
 	pinfo.lcd.v_back_porch = 6;
 	pinfo.lcd.v_front_porch = 0;
diff --git a/drivers/video/msm/mddi_toshiba_wvga.c b/drivers/video/msm/mddi_toshiba_wvga.c
index ad4ce46..c1925e1 100644
--- a/drivers/video/msm/mddi_toshiba_wvga.c
+++ b/drivers/video/msm/mddi_toshiba_wvga.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, 2012 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
@@ -34,6 +34,7 @@
 	pinfo.wait_cycle = 0;
 	pinfo.bpp = 18;
 	pinfo.lcd.vsync_enable = TRUE;
+	pinfo.mddi.is_type1 = TRUE;
 	pinfo.lcd.refx100 = 6118;
 	pinfo.lcd.v_back_porch = 6;
 	pinfo.lcd.v_front_porch = 0;
diff --git a/drivers/video/msm/mddi_toshiba_wvga_pt.c b/drivers/video/msm/mddi_toshiba_wvga_pt.c
index 7a9fb2d..8da1485 100644
--- a/drivers/video/msm/mddi_toshiba_wvga_pt.c
+++ b/drivers/video/msm/mddi_toshiba_wvga_pt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, 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
@@ -45,6 +45,7 @@
 	pinfo.bpp = 18;
 	pinfo.lcd.vsync_enable = TRUE;
 	pinfo.lcd.refx100 = 6102; /* adjust refx100 to prevent tearing */
+	pinfo.mddi.is_type1 = TRUE;
 	pinfo.lcd.v_back_porch = 8;     /* vsw=10 + vbp = 8 */
 	pinfo.lcd.v_front_porch = 2;
 	pinfo.lcd.v_pulse_width = 10;
diff --git a/drivers/video/msm/mdp4_dtv.c b/drivers/video/msm/mdp4_dtv.c
index 09bc9c2..e3115a3 100644
--- a/drivers/video/msm/mdp4_dtv.c
+++ b/drivers/video/msm/mdp4_dtv.c
@@ -109,7 +109,6 @@
 		clk_disable(ebi1_clk);
 #endif
 	mdp4_extn_disp = 0;
-	mdp_footswitch_ctrl(FALSE);
 	return ret;
 }
 
@@ -127,7 +126,6 @@
 		pm_qos_rate = panel_pixclock_freq / 1000 ;
 	else
 		pm_qos_rate = 58000;
-	mdp_footswitch_ctrl(TRUE);
 	mdp4_extn_disp = 1;
 #ifdef CONFIG_MSM_BUS_SCALING
 	if (dtv_bus_scale_handle > 0)
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index a3b03b8..cc03e97 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -2278,19 +2278,23 @@
 		mfd->use_ov0_blt |= (use_blt << (pipe->pipe_ndx-1));
 	}
 
-	if (!IS_ERR_OR_NULL(mfd->iclient)) {
-		if (pipe->flags & MDP_SECURE_OVERLAY_SESSION)
-			mfd->mem_hid |= ION_SECURE;
-		else
-			mfd->mem_hid &= ~ION_SECURE;
-	}
-
 	/* return id back to user */
 	req->id = pipe->pipe_ndx;	/* pipe_ndx start from 1 */
 	pipe->req_data = *req;		/* keep original req */
 
 	pipe->flags = req->flags;
 
+	if (!IS_ERR_OR_NULL(mfd->iclient)) {
+		pr_debug("pipe->flags 0x%x\n", pipe->flags);
+		if (pipe->flags & MDP_SECURE_OVERLAY_SESSION) {
+			mfd->mem_hid &= ~BIT(ION_IOMMU_HEAP_ID);
+			mfd->mem_hid |= ION_SECURE;
+		} else {
+			mfd->mem_hid |= BIT(ION_IOMMU_HEAP_ID);
+			mfd->mem_hid &= ~ION_SECURE;
+		}
+	}
+
 	if (pipe->flags & MDP_SHARPENING) {
 		bool test = ((pipe->req_data.dpp.sharp_strength > 0) &&
 			((req->src_rect.w > req->dst_rect.w) &&
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index 4342373..4d0d053 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -230,6 +230,7 @@
 	if (mfd->key != MFD_KEY)
 		return -EINVAL;
 
+	mdp_footswitch_ctrl(TRUE);
 	mdp4_overlay_panel_mode(MDP4_MIXER1, MDP4_PANEL_DTV);
 
 	/* Allocate dtv_pipe at dtv_on*/
@@ -266,6 +267,7 @@
 	mdp4_overlay_panel_mode_unset(MDP4_MIXER1, MDP4_PANEL_DTV);
 
 	ret = panel_next_off(pdev);
+	mdp_footswitch_ctrl(FALSE);
 
 	dev_info(&pdev->dev, "mdp4_overlay_dtv: off");
 	return ret;
diff --git a/drivers/video/msm/mdp4_overlay_writeback.c b/drivers/video/msm/mdp4_overlay_writeback.c
index 7739837..d8e7998 100644
--- a/drivers/video/msm/mdp4_overlay_writeback.c
+++ b/drivers/video/msm/mdp4_overlay_writeback.c
@@ -258,7 +258,9 @@
 	struct msmfb_writeback_data_list *node = NULL;
 	mutex_lock(&mfd->unregister_mutex);
 	mutex_lock(&mfd->writeback_mutex);
-	if (!list_empty(&mfd->writeback_free_queue)) {
+	if (!list_empty(&mfd->writeback_free_queue)
+		&& mfd->writeback_state != WB_STOPING
+		&& mfd->writeback_state != WB_STOP) {
 		node = list_first_entry(&mfd->writeback_free_queue,
 				struct msmfb_writeback_data_list, active_entry);
 	}
@@ -306,7 +308,9 @@
 
 	mutex_lock(&mfd->unregister_mutex);
 	mutex_lock(&mfd->writeback_mutex);
-	if (!list_empty(&mfd->writeback_free_queue)) {
+	if (!list_empty(&mfd->writeback_free_queue)
+		&& mfd->writeback_state != WB_STOPING
+		&& mfd->writeback_state != WB_STOP) {
 		node = list_first_entry(&mfd->writeback_free_queue,
 				struct msmfb_writeback_data_list, active_entry);
 	}
diff --git a/drivers/video/msm/mdp4_util.c b/drivers/video/msm/mdp4_util.c
index d15e115..dc0756e 100644
--- a/drivers/video/msm/mdp4_util.c
+++ b/drivers/video/msm/mdp4_util.c
@@ -2555,9 +2555,10 @@
 	}
 
 	if (!IS_ERR_OR_NULL(mfd->iclient)) {
-		pr_info("%s:%d ion based allocation\n", __func__, __LINE__);
-		buf->ihdl = ion_alloc(mfd->iclient, buf->size, 4,
-			(1 << mfd->mem_hid));
+		pr_info("%s:%d ion based allocation mfd->mem_hid 0x%x\n",
+			__func__, __LINE__, mfd->mem_hid);
+		buf->ihdl = ion_alloc(mfd->iclient, buf->size, SZ_4K,
+			mfd->mem_hid);
 		if (!IS_ERR_OR_NULL(buf->ihdl)) {
 			if (ion_phys(mfd->iclient, buf->ihdl,
 				&addr, &len)) {
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 1b0dfbe..7adbdae 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -1193,7 +1193,10 @@
 		((PAGE_SIZE - remainder)/fix->line_length) * mfd->fb_page;
 	var->bits_per_pixel = bpp * 8;	/* FrameBuffer color depth */
 	if (mfd->dest == DISPLAY_LCD) {
-		var->reserved[4] = panel_info->lcd.refx100 / 100;
+		if (panel_info->type == MDDI_PANEL && panel_info->mddi.is_type1)
+			var->reserved[4] = panel_info->lcd.refx100 / (100 * 2);
+		else
+			var->reserved[4] = panel_info->lcd.refx100 / 100;
 	} else {
 		if (panel_info->type == MIPI_VIDEO_PANEL) {
 			var->reserved[4] = panel_info->mipi.frame_rate;
diff --git a/drivers/video/msm/msm_fb_panel.h b/drivers/video/msm/msm_fb_panel.h
index a4072c8..7744e7a 100644
--- a/drivers/video/msm/msm_fb_panel.h
+++ b/drivers/video/msm/msm_fb_panel.h
@@ -86,6 +86,7 @@
 
 struct mddi_panel_info {
 	__u32 vdopkt;
+	boolean is_type1;
 };
 
 struct mipi_panel_info {
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
index 8eba8bd..830c777c3 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_interrupt_handler.c
@@ -1236,6 +1236,9 @@
 		if (vidc_msg_timing)
 			ddl_calc_core_proc_time(__func__, DEC_OP_TIME);
 		ddl_process_decoder_metadata(ddl);
+		vidc_sm_get_aspect_ratio_info(
+			&ddl->shared_mem[ddl->command_channel],
+			&output_vcd_frm->aspect_ratio_info);
 		ddl_context->ddl_callback(VCD_EVT_RESP_OUTPUT_DONE,
 			vcd_status, output_frame,
 			sizeof(struct ddl_frame_data_tag),
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
index c46a349..cce779e 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
@@ -184,6 +184,14 @@
 #define VIDC_SM_METADATA_ENABLE_QP_BMSK              0x1
 #define VIDC_SM_METADATA_ENABLE_QP_SHFT              0
 
+#define VIDC_SM_ASPECT_RATIO_INFO_ADDR               0x00c8
+#define VIDC_SM_MPEG4_ASPECT_RATIO_INFO_BMSK         0xf
+#define VIDC_SM_MPEG4_ASPECT_RATIO_INFO_SHFT         0x0
+#define VIDC_SM_EXTENDED_PAR_ADDR                    0x00cc
+#define VIDC_SM_EXTENDED_PAR_WIDTH_BMSK              0xffff0000
+#define VIDC_SM_EXTENDED_PAR_WIDTH_SHFT              0xf
+#define VIDC_SM_EXTENDED_PAR_HEIGHT_BMSK             0x0000ffff
+#define VIDC_SM_EXTENDED_PAR_HEIGHT_SHFT             0x0
 
 #define VIDC_SM_METADATA_STATUS_ADDR         0x003c
 #define VIDC_SM_METADATA_STATUS_STATUS_BMSK  0x1
@@ -770,3 +778,24 @@
 	DDL_MEM_WRITE_32(shared_mem, VIDC_SM_NUM_STUFF_BYTES_CONSUME_ADDR,
 	consume_info);
 }
+
+void vidc_sm_get_aspect_ratio_info(struct ddl_buf_addr *shared_mem,
+	struct vcd_aspect_ratio *aspect_ratio_info)
+{
+	u32 extended_par_info = 0;
+	aspect_ratio_info->aspect_ratio = DDL_MEM_READ_32(shared_mem,
+				VIDC_SM_ASPECT_RATIO_INFO_ADDR);
+
+	if (aspect_ratio_info->aspect_ratio == 0x0f) {
+		extended_par_info = DDL_MEM_READ_32(shared_mem,
+			VIDC_SM_EXTENDED_PAR_ADDR);
+		aspect_ratio_info->extended_par_width =
+			VIDC_GETFIELD(extended_par_info,
+			VIDC_SM_EXTENDED_PAR_WIDTH_BMSK,
+			VIDC_SM_EXTENDED_PAR_WIDTH_SHFT);
+		aspect_ratio_info->extended_par_height =
+			VIDC_GETFIELD(extended_par_info,
+			VIDC_SM_EXTENDED_PAR_HEIGHT_BMSK,
+			VIDC_SM_EXTENDED_PAR_HEIGHT_SHFT);
+	}
+}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
index 798a537..b0e6758 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.h
@@ -179,4 +179,6 @@
 void vidc_sm_set_decoder_stuff_bytes_consumption(
 	struct ddl_buf_addr *shared_mem,
 	enum vidc_sm_num_stuff_bytes_consume_info consume_info);
+void vidc_sm_get_aspect_ratio_info(struct ddl_buf_addr *shared_mem,
+	struct vcd_aspect_ratio *aspect_ratio_info);
 #endif
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
index 7fbad23..61deb8d 100644
--- a/drivers/video/msm/vidc/common/dec/vdec.c
+++ b/drivers/video/msm/vidc/common/dec/vdec.c
@@ -237,6 +237,7 @@
 	enum vdec_picture pic_type;
 	u32 ion_flag = 0;
 	struct ion_handle *buff_handle = NULL;
+	struct vdec_output_frameinfo  *output_frame;
 
 	if (!client_ctx || !vcd_frame_data) {
 		ERR("vid_dec_input_frame_done() NULL pointer\n");
@@ -329,6 +330,13 @@
 		}
 		vdec_msg->vdec_msg_info.msgdata.output_frame.pic_type =
 			pic_type;
+		output_frame = &vdec_msg->vdec_msg_info.msgdata.output_frame;
+		output_frame->aspect_ratio_info.aspect_ratio =
+			vcd_frame_data->aspect_ratio_info.aspect_ratio;
+		output_frame->aspect_ratio_info.par_width =
+			vcd_frame_data->aspect_ratio_info.extended_par_width;
+		output_frame->aspect_ratio_info.par_height =
+			vcd_frame_data->aspect_ratio_info.extended_par_height;
 		vdec_msg->vdec_msg_info.msgdatasize =
 		    sizeof(struct vdec_output_frameinfo);
 	} else {
diff --git a/include/linux/msm_audio.h b/include/linux/msm_audio.h
index 8a35ca0..f2a39e4 100644
--- a/include/linux/msm_audio.h
+++ b/include/linux/msm_audio.h
@@ -1,6 +1,7 @@
 /* include/linux/msm_audio.h
  *
  * Copyright (C) 2008 Google, Inc.
+ * Copyright (c) 2012 Code Aurora Forum. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -63,6 +64,9 @@
 					unsigned short)
 #define AUDIO_GET_BITSTREAM_ERROR_INFO _IOR(AUDIO_IOCTL_MAGIC, 42, \
 			       struct msm_audio_bitstream_error_info)
+
+#define AUDIO_SET_SRS_TRUMEDIA_PARAM _IOW(AUDIO_IOCTL_MAGIC, 43, unsigned)
+
 /* Qualcomm extensions */
 #define AUDIO_SET_STREAM_CONFIG   _IOW(AUDIO_IOCTL_MAGIC, 80, \
 				struct msm_audio_stream_config)
@@ -132,6 +136,8 @@
 #define IIR_ENABLE		0x0004
 #define QCONCERT_PLUS_ENABLE	0x0008
 #define MBADRC_ENABLE		0x0010
+#define SRS_ENABLE		0x0020
+#define SRS_DISABLE	0x0040
 
 #define AGC_ENABLE		0x0001
 #define NS_ENABLE		0x0002
diff --git a/include/linux/msm_vidc_dec.h b/include/linux/msm_vidc_dec.h
index 9c742b5..0c03e13 100644
--- a/include/linux/msm_vidc_dec.h
+++ b/include/linux/msm_vidc_dec.h
@@ -514,6 +514,12 @@
 	uint32_t   bottom;
 };
 
+struct vdec_aspectratioinfo {
+	uint32_t aspect_ratio;
+	uint32_t par_width;
+	uint32_t par_height;
+};
+
 struct vdec_output_frameinfo {
 	void __user *bufferaddr;
 	size_t offset;
@@ -525,6 +531,7 @@
 	void *input_frame_clientdata;
 	struct vdec_framesize framesize;
 	enum vdec_interlaced_format interlaced_format;
+	struct vdec_aspectratioinfo aspect_ratio_info;
 };
 
 union vdec_msgdata {
diff --git a/include/media/msm/vcd_api.h b/include/media/msm/vcd_api.h
index 6304c93..20d3ef9 100644
--- a/include/media/msm/vcd_api.h
+++ b/include/media/msm/vcd_api.h
@@ -53,6 +53,12 @@
 	VCD_PWR_STATE_SLEEP,
 };
 
+struct vcd_aspect_ratio {
+	u32 aspect_ratio;
+	u32 extended_par_width;
+	u32 extended_par_height;
+};
+
 struct vcd_frame_data {
 	u8 *virtual;
 	u8 *physical;
@@ -71,6 +77,7 @@
 	u8 *desc_buf;
 	u32 desc_size;
 	struct ion_handle *buff_ion_handle;
+	struct vcd_aspect_ratio aspect_ratio_info;
 };
 
 struct vcd_sequence_hdr {
diff --git a/sound/soc/msm/qdsp6/q6voice.c b/sound/soc/msm/qdsp6/q6voice.c
index 0376f34..3b46a50 100644
--- a/sound/soc/msm/qdsp6/q6voice.c
+++ b/sound/soc/msm/qdsp6/q6voice.c
@@ -34,6 +34,11 @@
 #define VOC_PATH_PASSIVE 0
 #define VOC_PATH_FULL 1
 
+/* CVP CAL Size: 245760 = 240 * 1024 */
+#define CVP_CAL_SIZE 245760
+/* CVS CAL Size: 49152 = 48 * 1024 */
+#define CVS_CAL_SIZE 49152
+
 static struct common_data common;
 
 static int voice_send_enable_vocproc_cmd(struct voice_data *v);
@@ -1130,6 +1135,7 @@
 	int ret = 0;
 	void *apr_cvs;
 	u16 cvs_handle;
+	uint32_t cal_paddr;
 
 	/* get the cvs cal data */
 	get_all_vocstrm_cal(&cal_block);
@@ -1146,6 +1152,21 @@
 		pr_err("%s: apr_cvs is NULL.\n", __func__);
 		return -EINVAL;
 	}
+
+	if (is_voip_session(v->session_id)) {
+		if (common.cvs_cal.buf) {
+			cal_paddr = common.cvs_cal.phy;
+
+			memcpy(common.cvs_cal.buf,
+				(void *) cal_block.cal_kvaddr,
+				cal_block.cal_size);
+		} else {
+			return -EINVAL;
+		}
+	} else {
+		cal_paddr = cal_block.cal_paddr;
+	}
+
 	cvs_handle = voice_get_cvs_handle(v);
 
 	/* fill in the header */
@@ -1158,7 +1179,7 @@
 	cvs_reg_cal_cmd.hdr.token = 0;
 	cvs_reg_cal_cmd.hdr.opcode = VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA;
 
-	cvs_reg_cal_cmd.cvs_cal_data.phys_addr = cal_block.cal_paddr;
+	cvs_reg_cal_cmd.cvs_cal_data.phys_addr = cal_paddr;
 	cvs_reg_cal_cmd.cvs_cal_data.mem_size = cal_block.cal_size;
 
 	v->cvs_state = CMD_STATUS_FAIL;
@@ -1241,6 +1262,7 @@
 	int ret = 0;
 	void *apr_cvp;
 	u16 cvp_handle;
+	uint32_t cal_paddr;
 
 	/* get all cvp cal data */
 	get_all_cvp_cal(&cal_block);
@@ -1257,6 +1279,15 @@
 		pr_err("%s: apr_cvp is NULL.\n", __func__);
 		return -EINVAL;
 	}
+
+	if (is_voip_session(v->session_id)) {
+		if (common.cvp_cal.buf)
+			cal_paddr = common.cvp_cal.phy;
+		else
+			return -EINVAL;
+	} else {
+		cal_paddr = cal_block.cal_paddr;
+	}
 	cvp_handle = voice_get_cvp_handle(v);
 
 	/* fill in the header */
@@ -1269,9 +1300,9 @@
 	cvp_map_mem_cmd.hdr.token = 0;
 	cvp_map_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_MAP_MEMORY;
 
-	pr_debug("%s, phy_addr:%d, mem_size:%d\n", __func__,
-		cal_block.cal_paddr, cal_block.cal_size);
-	cvp_map_mem_cmd.vss_map_mem.phys_addr = cal_block.cal_paddr;
+	pr_debug("%s, phy_addr:0x%x, mem_size:%d\n", __func__,
+		cal_paddr, cal_block.cal_size);
+	cvp_map_mem_cmd.vss_map_mem.phys_addr = cal_paddr;
 	cvp_map_mem_cmd.vss_map_mem.mem_size = cal_block.cal_size;
 	cvp_map_mem_cmd.vss_map_mem.mem_pool_id =
 				VSS_ICOMMON_MAP_MEMORY_SHMEM8_4K_POOL;
@@ -1302,6 +1333,7 @@
 	int ret = 0;
 	void *apr_cvp;
 	u16 cvp_handle;
+	uint32_t cal_paddr;
 
 	get_all_cvp_cal(&cal_block);
 	if (cal_block.cal_size == 0)
@@ -1317,6 +1349,12 @@
 		pr_err("%s: apr_cvp is NULL.\n", __func__);
 		return -EINVAL;
 	}
+
+	if (is_voip_session(v->session_id))
+		cal_paddr = common.cvp_cal.phy;
+	else
+		cal_paddr = cal_block.cal_paddr;
+
 	cvp_handle = voice_get_cvp_handle(v);
 
 	/* fill in the header */
@@ -1329,7 +1367,7 @@
 	cvp_unmap_mem_cmd.hdr.token = 0;
 	cvp_unmap_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_UNMAP_MEMORY;
 
-	cvp_unmap_mem_cmd.vss_unmap_mem.phys_addr = cal_block.cal_paddr;
+	cvp_unmap_mem_cmd.vss_unmap_mem.phys_addr = cal_paddr;
 
 	v->cvp_state = CMD_STATUS_FAIL;
 	ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_unmap_mem_cmd);
@@ -1357,6 +1395,7 @@
 	int ret = 0;
 	void *apr_cvs;
 	u16 cvs_handle;
+	uint32_t cal_paddr;
 
 	/* get all cvs cal data */
 	get_all_vocstrm_cal(&cal_block);
@@ -1373,6 +1412,16 @@
 		pr_err("%s: apr_cvs is NULL.\n", __func__);
 		return -EINVAL;
 	}
+
+	if (is_voip_session(v->session_id)) {
+		if (common.cvs_cal.buf)
+			cal_paddr = common.cvs_cal.phy;
+		else
+			return -EINVAL;
+	} else {
+		cal_paddr = cal_block.cal_paddr;
+	}
+
 	cvs_handle = voice_get_cvs_handle(v);
 
 	/* fill in the header */
@@ -1385,9 +1434,9 @@
 	cvs_map_mem_cmd.hdr.token = 0;
 	cvs_map_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_MAP_MEMORY;
 
-	pr_debug("%s, phys_addr: %d, mem_size: %d\n", __func__,
-		cal_block.cal_paddr, cal_block.cal_size);
-	cvs_map_mem_cmd.vss_map_mem.phys_addr = cal_block.cal_paddr;
+	pr_debug("%s, phys_addr: 0x%x, mem_size: %d\n", __func__,
+		cal_paddr, cal_block.cal_size);
+	cvs_map_mem_cmd.vss_map_mem.phys_addr = cal_paddr;
 	cvs_map_mem_cmd.vss_map_mem.mem_size = cal_block.cal_size;
 	cvs_map_mem_cmd.vss_map_mem.mem_pool_id =
 				VSS_ICOMMON_MAP_MEMORY_SHMEM8_4K_POOL;
@@ -1418,6 +1467,7 @@
 	int ret = 0;
 	void *apr_cvs;
 	u16 cvs_handle;
+	uint32_t cal_paddr;
 
 	get_all_vocstrm_cal(&cal_block);
 	if (cal_block.cal_size == 0)
@@ -1433,6 +1483,12 @@
 		pr_err("%s: apr_cvs is NULL.\n", __func__);
 		return -EINVAL;
 	}
+
+	if (is_voip_session(v->session_id))
+		cal_paddr = common.cvs_cal.phy;
+	else
+		cal_paddr = cal_block.cal_paddr;
+
 	cvs_handle = voice_get_cvs_handle(v);
 
 	/* fill in the header */
@@ -1445,7 +1501,7 @@
 	cvs_unmap_mem_cmd.hdr.token = 0;
 	cvs_unmap_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_UNMAP_MEMORY;
 
-	cvs_unmap_mem_cmd.vss_unmap_mem.phys_addr = cal_block.cal_paddr;
+	cvs_unmap_mem_cmd.vss_unmap_mem.phys_addr = cal_paddr;
 
 	v->cvs_state = CMD_STATUS_FAIL;
 	ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_unmap_mem_cmd);
@@ -1473,6 +1529,7 @@
 	int ret = 0;
 	void *apr_cvp;
 	u16 cvp_handle;
+	uint32_t cal_paddr;
 
       /* get the cvp cal data */
 	get_all_vocproc_cal(&cal_block);
@@ -1489,6 +1546,21 @@
 		pr_err("%s: apr_cvp is NULL.\n", __func__);
 		return -EINVAL;
 	}
+
+	if (is_voip_session(v->session_id)) {
+		if (common.cvp_cal.buf) {
+			cal_paddr = common.cvp_cal.phy;
+
+			memcpy(common.cvp_cal.buf,
+				(void *)cal_block.cal_kvaddr,
+				cal_block.cal_size);
+		} else {
+			return -EINVAL;
+		}
+	} else {
+		cal_paddr = cal_block.cal_paddr;
+	}
+
 	cvp_handle = voice_get_cvp_handle(v);
 
 	/* fill in the header */
@@ -1501,7 +1573,7 @@
 	cvp_reg_cal_cmd.hdr.token = 0;
 	cvp_reg_cal_cmd.hdr.opcode = VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA;
 
-	cvp_reg_cal_cmd.cvp_cal_data.phys_addr = cal_block.cal_paddr;
+	cvp_reg_cal_cmd.cvp_cal_data.phys_addr = cal_paddr;
 	cvp_reg_cal_cmd.cvp_cal_data.mem_size = cal_block.cal_size;
 
 	v->cvp_state = CMD_STATUS_FAIL;
@@ -1580,14 +1652,18 @@
 static int voice_send_cvp_register_vol_cal_table_cmd(struct voice_data *v)
 {
 	struct cvp_register_vol_cal_table_cmd cvp_reg_cal_tbl_cmd;
-	struct acdb_cal_block cal_block;
+	struct acdb_cal_block vol_block;
+	struct acdb_cal_block voc_block;
 	int ret = 0;
 	void *apr_cvp;
 	u16 cvp_handle;
+	uint32_t cal_paddr;
 
 	/* get the cvp vol cal data */
-	get_all_vocvol_cal(&cal_block);
-	if (cal_block.cal_size == 0)
+	get_all_vocvol_cal(&vol_block);
+	get_all_vocproc_cal(&voc_block);
+
+	if (vol_block.cal_size == 0)
 		goto fail;
 
 	if (v == NULL) {
@@ -1600,6 +1676,21 @@
 		pr_err("%s: apr_cvp is NULL.\n", __func__);
 		return -EINVAL;
 	}
+
+	if (is_voip_session(v->session_id)) {
+		if (common.cvp_cal.buf) {
+			cal_paddr = common.cvp_cal.phy + voc_block.cal_size;
+
+			memcpy(common.cvp_cal.buf + voc_block.cal_size,
+				(void *) vol_block.cal_kvaddr,
+				vol_block.cal_size);
+		} else {
+			return -EINVAL;
+		}
+	} else {
+		cal_paddr = vol_block.cal_paddr;
+	}
+
 	cvp_handle = voice_get_cvp_handle(v);
 
 	/* fill in the header */
@@ -1613,8 +1704,8 @@
 	cvp_reg_cal_tbl_cmd.hdr.opcode =
 				VSS_IVOCPROC_CMD_REGISTER_VOLUME_CAL_TABLE;
 
-	cvp_reg_cal_tbl_cmd.cvp_vol_cal_tbl.phys_addr = cal_block.cal_paddr;
-	cvp_reg_cal_tbl_cmd.cvp_vol_cal_tbl.mem_size = cal_block.cal_size;
+	cvp_reg_cal_tbl_cmd.cvp_vol_cal_tbl.phys_addr = cal_paddr;
+	cvp_reg_cal_tbl_cmd.cvp_vol_cal_tbl.mem_size = vol_block.cal_size;
 
 	v->cvp_state = CMD_STATUS_FAIL;
 	ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_reg_cal_tbl_cmd);
@@ -3641,9 +3732,73 @@
 static int __init voice_init(void)
 {
 	int rc = 0, i = 0;
+	int len;
 
 	memset(&common, 0, sizeof(struct common_data));
 
+	/* Allocate memory for VoIP calibration */
+	common.client = msm_ion_client_create(UINT_MAX, "voip_client");
+	if (IS_ERR_OR_NULL((void *)common.client)) {
+		pr_err("%s: ION create client for Voip failed\n", __func__);
+		goto cont;
+	}
+	common.cvp_cal.handle = ion_alloc(common.client, CVP_CAL_SIZE, SZ_4K,
+					  ION_HEAP(ION_AUDIO_HEAP_ID));
+	if (IS_ERR_OR_NULL((void *) common.cvp_cal.handle)) {
+		pr_err("%s: ION memory allocation for CVP failed\n",
+			__func__);
+		ion_client_destroy(common.client);
+		goto cont;
+	}
+
+	rc = ion_phys(common.client, common.cvp_cal.handle,
+		  (ion_phys_addr_t *)&common.cvp_cal.phy, (size_t *)&len);
+	if (rc) {
+		pr_err("%s: ION Get Physical for cvp failed, rc = %d\n",
+			__func__, rc);
+		ion_free(common.client, common.cvp_cal.handle);
+		ion_client_destroy(common.client);
+		goto cont;
+	}
+
+	common.cvp_cal.buf = ion_map_kernel(common.client,
+					common.cvp_cal.handle, 0);
+	if (IS_ERR_OR_NULL((void *) common.cvp_cal.buf)) {
+		pr_err("%s: ION memory mapping for cvp failed\n", __func__);
+		common.cvp_cal.buf = NULL;
+		ion_free(common.client, common.cvp_cal.handle);
+		ion_client_destroy(common.client);
+		goto cont;
+	}
+	memset((void *)common.cvp_cal.buf, 0, CVP_CAL_SIZE);
+
+	common.cvs_cal.handle = ion_alloc(common.client, CVS_CAL_SIZE, SZ_4K,
+					 ION_HEAP(ION_AUDIO_HEAP_ID));
+	if (IS_ERR_OR_NULL((void *) common.cvs_cal.handle)) {
+		pr_err("%s: ION memory allocation for CVS failed\n",
+			__func__);
+		goto cont;
+	}
+
+	rc = ion_phys(common.client, common.cvs_cal.handle,
+		  (ion_phys_addr_t *)&common.cvs_cal.phy, (size_t *)&len);
+	if (rc) {
+		pr_err("%s: ION Get Physical for cvs failed, rc = %d\n",
+			__func__, rc);
+		ion_free(common.client, common.cvs_cal.handle);
+		goto cont;
+	}
+
+	common.cvs_cal.buf = ion_map_kernel(common.client,
+					common.cvs_cal.handle, 0);
+	if (IS_ERR_OR_NULL((void *) common.cvs_cal.buf)) {
+		pr_err("%s: ION memory mapping for cvs failed\n", __func__);
+		common.cvs_cal.buf = NULL;
+		ion_free(common.client, common.cvs_cal.handle);
+		goto cont;
+	}
+	memset((void *)common.cvs_cal.buf, 0, CVS_CAL_SIZE);
+cont:
 	/* set default value */
 	common.default_mute_val = 1;  /* default is mute */
 	common.default_vol_val = 0;
diff --git a/sound/soc/msm/qdsp6/q6voice.h b/sound/soc/msm/qdsp6/q6voice.h
index 0edf1c9..0fc7a01 100644
--- a/sound/soc/msm/qdsp6/q6voice.h
+++ b/sound/soc/msm/qdsp6/q6voice.h
@@ -13,6 +13,7 @@
 #define __QDSP6VOICE_H__
 
 #include <mach/qdsp6v2/apr.h>
+#include <linux/ion.h>
 
 #define MAX_VOC_PKT_SIZE 642
 #define SESSION_NAME_LEN 20
@@ -871,6 +872,12 @@
 	struct voice_rec_route_state rec_route_state;
 };
 
+struct cal_mem {
+	struct ion_handle *handle;
+	uint32_t phy;
+	void *buf;
+};
+
 #define MAX_VOC_SESSIONS 2
 #define SESSION_ID_BASE 0xFFF0
 
@@ -887,6 +894,10 @@
 	/* APR to CVP in the Q6 */
 	void *apr_q6_cvp;
 
+	struct ion_client *client;
+	struct cal_mem cvp_cal;
+	struct cal_mem cvs_cal;
+
 	struct mutex common_lock;
 
 	struct mvs_driver_info mvs_info;