Merge "msm: 8960: Add correct PASR mask support" into msm-3.0
diff --git a/Documentation/devicetree/bindings/spi/spi_qsd.txt b/Documentation/devicetree/bindings/spi/spi_qsd.txt
new file mode 100644
index 0000000..5839f63
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/spi_qsd.txt
@@ -0,0 +1,16 @@
+Qualcomm Serial Peripheral Interface (SPI)
+
+Required properties:
+- compatible : should be "qcom,spi-qup-v2".
+- reg : offset and length of the QUP register map.
+- interrupts : should contain the QUP core interrupt.
+- spi-max-frequency : specifies maximum SPI clock frequency, Units - Hz.
+
+Example:
+	spi@f9924000 {
+		compatible = "qcom,spi-qup-v2";
+		reg = <0xf9924000 0x1000>;
+		interrupts = <96>;
+		spi-max-frequency = <24000000>;
+	};
+
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index d79aead..b1db115 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -266,3 +266,6 @@
   pcim_iounmap()
   pcim_iomap_table()	: array of mapped addresses indexed by BAR
   pcim_iomap_regions()	: do request_region() and iomap() on multiple BARs
+
+REGULATOR
+  devm_regulator_get()
diff --git a/arch/arm/boot/dts/msmcopper.dts b/arch/arm/boot/dts/msmcopper.dts
index 6561c71..b00237a 100644
--- a/arch/arm/boot/dts/msmcopper.dts
+++ b/arch/arm/boot/dts/msmcopper.dts
@@ -70,4 +70,10 @@
 		qcom,bam-dma-res-pipes = <6>;
 	};
 
+	spi@f9924000 {
+		compatible = "qcom,spi-qup-v2";
+		reg = <0xf9924000 0x1000>;
+		interrupts = <96>;
+		spi-max-frequency = <24000000>;
+	};
 };
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index ca974b2..00ff580 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -45,6 +45,7 @@
 CONFIG_MSM7X27A_AUDIO=y
 CONFIG_MSM_DMA_TEST=y
 # CONFIG_MSM_JTAG_V7 is not set
+CONFIG_MSM_SLEEP_STATS_DEVICE=y
 CONFIG_BT_MSM_PINTEST=y
 CONFIG_MSM_RPC_VIBRATOR=y
 CONFIG_PM8XXX_RPC_VIBRATOR=y
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index cfa06a8..3cf01a1 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -45,6 +45,7 @@
 CONFIG_MSM7X27A_AUDIO=y
 CONFIG_MSM_DMA_TEST=y
 # CONFIG_MSM_JTAG_V7 is not set
+CONFIG_MSM_SLEEP_STATS_DEVICE=y
 CONFIG_BT_MSM_PINTEST=y
 CONFIG_MSM_RPC_VIBRATOR=y
 CONFIG_PM8XXX_RPC_VIBRATOR=y
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 0faa7ea..4328ac3 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -383,8 +383,7 @@
 	 */
 	if (max_cpus > ncores)
 		max_cpus = ncores;
-
-	if (max_cpus > 1) {
+	if (ncores > 1 && max_cpus) {
 		/*
 		 * Enable the local timer or broadcast device for the
 		 * boot CPU, but only if we have more than one CPU.
@@ -392,6 +391,14 @@
 		percpu_timer_setup();
 
 		/*
+		 * Initialise the present map, which describes the set of CPUs
+		 * actually populated at the present time. A platform should
+		 * re-initialize the map in platform_smp_prepare_cpus() if
+		 * present != possible (e.g. physical hotplug).
+		 */
+		init_cpu_present(&cpu_possible_map);
+
+		/*
 		 * Initialise the SCU if there are more than one CPU
 		 * and let them know where to start.
 		 */
diff --git a/arch/arm/mach-exynos4/platsmp.c b/arch/arm/mach-exynos4/platsmp.c
index c5e65a0..b68d5bd 100644
--- a/arch/arm/mach-exynos4/platsmp.c
+++ b/arch/arm/mach-exynos4/platsmp.c
@@ -154,14 +154,6 @@
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
 {
-	int i;
-
-	/*
-	 * Initialise the present map, which describes the set of CPUs
-	 * actually populated at the present time.
-	 */
-	for (i = 0; i < max_cpus; i++)
-		set_cpu_present(i, true);
 
 	scu_enable(scu_base_addr());
 
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index ee9b2de..9df90cd 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -1845,6 +1845,9 @@
 	depends on CPU_IDLE
 	default n
 
+config MSM_SLEEP_STATS_DEVICE
+	bool "Enable exporting of MSM sleep device stats to userspace"
+
 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 bae4678..8b866d8 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -301,7 +301,8 @@
 endif
 endif
 
-obj-$(CONFIG_MSM_SLEEP_STATS) += msm_rq_stats.o idle_stats.o idle_stats_device.o
+obj-$(CONFIG_MSM_SLEEP_STATS) += msm_rq_stats.o idle_stats.o
+obj-$(CONFIG_MSM_SLEEP_STATS_DEVICE) += idle_stats_device.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/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index bfe4f81..0e4c756 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -1241,9 +1241,25 @@
 				struct dentry *dent,
 				int (*fill)(char *buf, int max))
 {
-	debugfs_create_file(name, mode, dent, fill, &debug_ops);
+	struct dentry *file;
+
+	file = debugfs_create_file(name, mode, dent, fill, &debug_ops);
+	if (IS_ERR(file))
+		pr_err("%s: debugfs create failed %d\n", __func__,
+				(int)PTR_ERR(file));
 }
 
+static void debug_create_multiple(const char *name, mode_t mode,
+				struct dentry *dent,
+				int (*fill)(char *buf, int max, loff_t *ppos))
+{
+	struct dentry *file;
+
+	file = debugfs_create_file(name, mode, dent, fill, &debug_ops_multiple);
+	if (IS_ERR(file))
+		pr_err("%s: debugfs create failed %d\n", __func__,
+				(int)PTR_ERR(file));
+}
 #endif
 
 static void notify_all(int event, unsigned long data)
@@ -1370,7 +1386,7 @@
 		else
 			called_before = 1;
 		if (wait_for_dfab) {
-			ret = wait_for_completion_interruptible_timeout(
+			ret = wait_for_completion_timeout(
 					&dfab_unvote_completion, HZ);
 			BUG_ON(ret == 0);
 		}
@@ -1389,7 +1405,7 @@
 	 */
 	if (wait_for_ack) {
 		bam_dmux_log("%s waiting for previous ack\n", __func__);
-		ret = wait_for_completion_interruptible_timeout(
+		ret = wait_for_completion_timeout(
 					&ul_wakeup_ack_completion, HZ);
 		BUG_ON(ret == 0);
 		wait_for_ack = 0;
@@ -1397,12 +1413,10 @@
 	INIT_COMPLETION(ul_wakeup_ack_completion);
 	power_vote(1);
 	bam_dmux_log("%s waiting for wakeup ack\n", __func__);
-	ret = wait_for_completion_interruptible_timeout(
-						&ul_wakeup_ack_completion, HZ);
+	ret = wait_for_completion_timeout(&ul_wakeup_ack_completion, HZ);
 	BUG_ON(ret == 0);
 	bam_dmux_log("%s waiting completion\n", __func__);
-	ret = wait_for_completion_interruptible_timeout(
-						&bam_connection_completion, HZ);
+	ret = wait_for_completion_timeout(&bam_connection_completion, HZ);
 	BUG_ON(ret == 0);
 
 	bam_is_connected = 1;
@@ -1497,7 +1511,7 @@
 		mutex_unlock(&dfab_status_lock);
 		return;
 	}
-	rc = clk_enable(dfab_clk);
+	rc = clk_prepare_enable(dfab_clk);
 	if (rc)
 		DMUX_LOG_KERR("bam_dmux vote for dfab failed rc = %d\n", rc);
 	dfab_is_on = 1;
@@ -1514,7 +1528,7 @@
 		mutex_unlock(&dfab_status_lock);
 		return;
 	}
-	clk_disable(dfab_clk);
+	clk_disable_unprepare(dfab_clk);
 	dfab_is_on = 0;
 	mutex_unlock(&dfab_status_lock);
 }
@@ -1986,8 +2000,7 @@
 		debug_create("tbl", 0444, dent, debug_tbl);
 		debug_create("ul_pkt_cnt", 0444, dent, debug_ul_pkt_cnt);
 		debug_create("stats", 0444, dent, debug_stats);
-		debugfs_create_file("log", 0444, dent, debug_log,
-				&debug_ops_multiple);
+		debug_create_multiple("log", 0444, dent, debug_log);
 	}
 #endif
 	ret = kfifo_alloc(&bam_dmux_state_log, PAGE_SIZE, GFP_KERNEL);
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index 1aedd55..0ba7434 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -46,6 +46,7 @@
 #include <linux/bootmem.h>
 #include <asm/setup.h>
 #include <mach/dma.h>
+#include <mach/msm_bus_board.h>
 
 #include "msm_watchdog.h"
 #include "board-8064.h"
@@ -558,6 +559,22 @@
 	},
 };
 
+static void __init apq8064_init_buses(void)
+{
+	msm_bus_rpm_set_mt_mask();
+	msm_bus_8064_apps_fabric_pdata.rpm_enabled = 1;
+	msm_bus_8064_sys_fabric_pdata.rpm_enabled = 1;
+	msm_bus_8064_mm_fabric_pdata.rpm_enabled = 1;
+	msm_bus_8064_apps_fabric.dev.platform_data =
+		&msm_bus_8064_apps_fabric_pdata;
+	msm_bus_8064_sys_fabric.dev.platform_data =
+		&msm_bus_8064_sys_fabric_pdata;
+	msm_bus_8064_mm_fabric.dev.platform_data =
+		&msm_bus_8064_mm_fabric_pdata;
+	msm_bus_8064_sys_fpb.dev.platform_data = &msm_bus_8064_sys_fpb_pdata;
+	msm_bus_8064_cpss_fpb.dev.platform_data = &msm_bus_8064_cpss_fpb_pdata;
+}
+
 static struct platform_device *common_devices[] __initdata = {
 	&apq8064_device_dmov,
 	&apq8064_device_qup_i2c_gsbi4,
@@ -619,6 +636,11 @@
 	&apq_pcm_afe,
 	&apq_cpudai_auxpcm_rx,
 	&apq_cpudai_auxpcm_tx,
+	&msm_bus_8064_apps_fabric,
+	&msm_bus_8064_sys_fabric,
+	&msm_bus_8064_mm_fabric,
+	&msm_bus_8064_sys_fpb,
+	&msm_bus_8064_cpss_fpb,
 };
 
 static struct platform_device *sim_devices[] __initdata = {
@@ -712,6 +734,7 @@
 						&apq8064_qup_spi_gsbi5_pdata;
 	apq8064_init_pmic();
 	apq8064_device_otg.dev.platform_data = &msm_otg_pdata;
+	apq8064_init_buses();
 	platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
 	apq8064_init_mmc();
 	slim_register_board_info(apq8064_slim_devices,
diff --git a/arch/arm/mach-msm/board-8930-gpiomux.c b/arch/arm/mach-msm/board-8930-gpiomux.c
index fc64ed2..84dbea8 100644
--- a/arch/arm/mach-msm/board-8930-gpiomux.c
+++ b/arch/arm/mach-msm/board-8930-gpiomux.c
@@ -156,29 +156,22 @@
 	.pull = GPIOMUX_PULL_DOWN,
 };
 #ifdef MSM8930_PHASE_2
-static struct gpiomux_setting hsusb_act_cfg = {
-	.func = GPIOMUX_FUNC_GPIO,
-	.drv = GPIOMUX_DRV_8MA,
-	.pull = GPIOMUX_PULL_UP,
-};
-
 static struct gpiomux_setting hsusb_sus_cfg = {
 	.func = GPIOMUX_FUNC_GPIO,
 	.drv = GPIOMUX_DRV_2MA,
-	.pull = GPIOMUX_PULL_DOWN,
+	.pull = GPIOMUX_PULL_NONE,
+	.dir = GPIOMUX_OUT_LOW,
 };
 static struct msm_gpiomux_config msm8930_hsusb_configs[] = {
 	{
 		.gpio = 63,     /* HSUSB_EXTERNAL_5V_LDO_EN */
 		.settings = {
-			[GPIOMUX_ACTIVE] = &hsusb_act_cfg,
 			[GPIOMUX_SUSPENDED] = &hsusb_sus_cfg,
 		},
 	},
 	{
 		.gpio = 97,     /* HSUSB_5V_EN */
 		.settings = {
-			[GPIOMUX_ACTIVE] = &hsusb_act_cfg,
 			[GPIOMUX_SUSPENDED] = &hsusb_sus_cfg,
 		},
 	},
diff --git a/arch/arm/mach-msm/board-8930-pmic.c b/arch/arm/mach-msm/board-8930-pmic.c
index 6cb69f6..2f59d9d 100644
--- a/arch/arm/mach-msm/board-8930-pmic.c
+++ b/arch/arm/mach-msm/board-8930-pmic.c
@@ -198,10 +198,49 @@
 	.wakeup			= 1,
 };
 
+static int pm8921_therm_mitigation[] = {
+	1100,
+	700,
+	600,
+	325,
+};
+
+#define MAX_VOLTAGE_MV		4200
+static struct pm8921_charger_platform_data pm8921_chg_pdata __devinitdata = {
+	.safety_time		= 180,
+	.update_time		= 60000,
+	.max_voltage		= MAX_VOLTAGE_MV,
+	.min_voltage		= 3200,
+	.resume_voltage_delta	= 100,
+	.term_current		= 100,
+	.cool_temp		= 10,
+	.warm_temp		= 40,
+	.temp_check_period	= 1,
+	.max_bat_chg_current	= 1100,
+	.cool_bat_chg_current	= 350,
+	.warm_bat_chg_current	= 350,
+	.cool_bat_voltage	= 4100,
+	.warm_bat_voltage	= 4100,
+	.thermal_mitigation	= pm8921_therm_mitigation,
+	.thermal_levels		= ARRAY_SIZE(pm8921_therm_mitigation),
+};
+
+static struct pm8xxx_ccadc_platform_data pm8xxx_ccadc_pdata = {
+	.r_sense		= 10,
+};
+
 static struct pm8xxx_misc_platform_data pm8xxx_misc_pdata = {
 	.priority		= 0,
 };
 
+static struct pm8921_bms_platform_data pm8921_bms_pdata __devinitdata = {
+	.r_sense		= 10,
+	.i_test			= 2500,
+	.v_failure		= 3000,
+	.calib_delay_ms		= 600000,
+	.max_voltage_uv		= MAX_VOLTAGE_MV * 1000,
+};
+
 static struct pm8038_platform_data pm8038_platform_data __devinitdata = {
 	.irq_pdata		= &pm8xxx_irq_pdata,
 	.gpio_pdata		= &pm8xxx_gpio_pdata,
@@ -210,7 +249,10 @@
 	.pwrkey_pdata		= &pm8xxx_pwrkey_pdata,
 	.misc_pdata		= &pm8xxx_misc_pdata,
 	.regulator_pdatas	= msm8930_pm8038_regulator_pdata,
+	.charger_pdata		= &pm8921_chg_pdata,
+	.bms_pdata		= &pm8921_bms_pdata,
 	.adc_pdata		= &pm8xxx_adc_pdata,
+	.ccadc_pdata		= &pm8xxx_ccadc_pdata,
 };
 
 static struct msm_ssbi_platform_data msm8930_ssbi_pm8038_pdata __devinitdata = {
diff --git a/arch/arm/mach-msm/board-8930-regulator.c b/arch/arm/mach-msm/board-8930-regulator.c
index cf7d6a9..fc9b58f 100644
--- a/arch/arm/mach-msm/board-8930-regulator.c
+++ b/arch/arm/mach-msm/board-8930-regulator.c
@@ -42,9 +42,11 @@
 };
 VREG_CONSUMERS(L5) = {
 	REGULATOR_SUPPLY("8038_l5",		NULL),
+	REGULATOR_SUPPLY("sdc_vdd",		"msm_sdcc.1"),
 };
 VREG_CONSUMERS(L6) = {
 	REGULATOR_SUPPLY("8038_l6",		NULL),
+	REGULATOR_SUPPLY("sdc_vdd",		"msm_sdcc.3"),
 };
 VREG_CONSUMERS(L7) = {
 	REGULATOR_SUPPLY("8038_l7",		NULL),
@@ -67,6 +69,7 @@
 	REGULATOR_SUPPLY("vdd_dig",		"3-004a"),
 	REGULATOR_SUPPLY("iris_vddio",		"wcnss_wlan.0"),
 	REGULATOR_SUPPLY("riva_vddpx",		"wcnss_wlan.0"),
+	REGULATOR_SUPPLY("sdc_vccq",		"msm_sdcc.1"),
 };
 VREG_CONSUMERS(L12) = {
 	REGULATOR_SUPPLY("8038_l12",		NULL),
@@ -99,6 +102,7 @@
 };
 VREG_CONSUMERS(L22) = {
 	REGULATOR_SUPPLY("8038_l22",		NULL),
+	REGULATOR_SUPPLY("sdc_vddp",		"msm_sdcc.3"),
 };
 VREG_CONSUMERS(L23) = {
 	REGULATOR_SUPPLY("8038_l23",		NULL),
diff --git a/arch/arm/mach-msm/board-8930-storage.c b/arch/arm/mach-msm/board-8930-storage.c
index d655ead..eee6d09 100644
--- a/arch/arm/mach-msm/board-8930-storage.c
+++ b/arch/arm/mach-msm/board-8930-storage.c
@@ -250,6 +250,8 @@
 /*TODO: Insert right replacement for PM8038 */
 #ifndef MSM8930_PHASE_2
 	.wpswitch_gpio	= PM8921_GPIO_PM_TO_SYS(16),
+#else
+	.wpswitch_gpio	= 66,
 #endif
 #endif
 	.vreg_data	= &mmc_slot_vreg_data[SDCC3],
@@ -259,6 +261,9 @@
 #ifndef MSM8930_PHASE_2
 	.status_gpio	= PM8921_GPIO_PM_TO_SYS(26),
 	.status_irq	= PM8921_GPIO_IRQ(PM8921_IRQ_BASE, 26),
+#else
+	.status_gpio	= 94,
+	.status_irq	= MSM_GPIO_TO_INT(94),
 #endif
 	.irq_flags	= IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 	.is_status_gpio_active_low = true,
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 533d4f7..fe125e3 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -117,21 +117,24 @@
 
 #endif
 
-#define MSM_PMEM_ADSP_SIZE         0x3800000
+#define MSM_PMEM_ADSP_SIZE         0x7800000
 #define MSM_PMEM_AUDIO_SIZE        0x2B4000
 #ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
 #define MSM_PMEM_SIZE 0x4000000 /* 64 Mbytes */
 #else
-#define MSM_PMEM_SIZE 0x1C00000 /* 28 Mbytes */
+#define MSM_PMEM_SIZE 0x2800000 /* 40 Mbytes */
 #endif
 
 
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 #define MSM_PMEM_KERNEL_EBI1_SIZE  0xB0C000
-#define MSM_ION_SF_SIZE		0x1800000 /* 24MB */
-#define MSM_ION_MM_SIZE		0x4000000 /* (64MB) */
+#define MSM_ION_SF_SIZE		MSM_PMEM_SIZE
+#define MSM_ION_MM_FW_SIZE	0x200000 /* (2MB) */
+#define MSM_ION_MM_SIZE		MSM_PMEM_ADSP_SIZE
+#define MSM_ION_QSECOM_SIZE	0x100000 /* (1MB) */
 #define MSM_ION_MFC_SIZE	SZ_8K
-#define MSM_ION_HEAP_NUM	5
+#define MSM_ION_AUDIO_SIZE	MSM_PMEM_AUDIO_SIZE
+#define MSM_ION_HEAP_NUM	8
 #else
 #define MSM_PMEM_KERNEL_EBI1_SIZE  0x110C000
 #define MSM_ION_HEAP_NUM	1
@@ -285,12 +288,20 @@
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 static struct ion_cp_heap_pdata cp_mm_ion_pdata = {
 	.permission_type = IPT_TYPE_MM_CARVEOUT,
+	.align = PAGE_SIZE,
 };
 
 static struct ion_cp_heap_pdata cp_mfc_ion_pdata = {
 	.permission_type = IPT_TYPE_MFC_SHAREDMEM,
+	.align = PAGE_SIZE,
 };
 static struct ion_co_heap_pdata co_ion_pdata = {
+	.adjacent_mem_id = INVALID_HEAP_ID,
+	.align = PAGE_SIZE,
+};
+static struct ion_co_heap_pdata fw_co_ion_pdata = {
+	.adjacent_mem_id = ION_CP_MM_HEAP_ID,
+	.align = SZ_128K,
 };
 #endif
 static struct ion_platform_data ion_pdata = {
@@ -308,7 +319,7 @@
 			.name	= ION_SF_HEAP_NAME,
 			.size	= MSM_ION_SF_SIZE,
 			.memory_type = ION_EBI_TYPE,
-			.extra_data = &co_ion_pdata,
+			.extra_data = (void *) &co_ion_pdata,
 		},
 		{
 			.id	= ION_CP_MM_HEAP_ID,
@@ -319,6 +330,14 @@
 			.extra_data = (void *) &cp_mm_ion_pdata,
 		},
 		{
+			.id	= ION_MM_FIRMWARE_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_MM_FIRMWARE_HEAP_NAME,
+			.size	= MSM_ION_MM_FW_SIZE,
+			.memory_type = ION_EBI_TYPE,
+			.extra_data = (void *) &fw_co_ion_pdata,
+		},
+		{
 			.id	= ION_CP_MFC_HEAP_ID,
 			.type	= ION_HEAP_TYPE_CP,
 			.name	= ION_MFC_HEAP_NAME,
@@ -331,6 +350,22 @@
 			.type	= ION_HEAP_TYPE_IOMMU,
 			.name	= ION_IOMMU_HEAP_NAME,
 		},
+		{
+			.id	= ION_QSECOM_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_QSECOM_HEAP_NAME,
+			.size	= MSM_ION_QSECOM_SIZE,
+			.memory_type = ION_EBI_TYPE,
+			.extra_data = (void *) &co_ion_pdata,
+		},
+		{
+			.id	= ION_AUDIO_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_AUDIO_HEAP_NAME,
+			.size	= MSM_ION_AUDIO_SIZE,
+			.memory_type = ION_EBI_TYPE,
+			.extra_data = (void *) &co_ion_pdata,
+		},
 #endif
 	}
 };
@@ -347,7 +382,10 @@
 #if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
 	msm8930_reserve_table[MEMTYPE_EBI1].size += MSM_ION_SF_SIZE;
 	msm8930_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MM_SIZE;
+	msm8930_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MM_FW_SIZE;
 	msm8930_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MFC_SIZE;
+	msm8930_reserve_table[MEMTYPE_EBI1].size += MSM_ION_QSECOM_SIZE;
+	msm8930_reserve_table[MEMTYPE_EBI1].size += MSM_ION_AUDIO_SIZE;
 #endif
 }
 
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index b19445d..598e18d 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -130,7 +130,7 @@
 
 #endif
 
-#define MSM_PMEM_ADSP_SIZE         0x4200000
+#define MSM_PMEM_ADSP_SIZE         0x7800000
 #define MSM_PMEM_AUDIO_SIZE        0x2B4000
 #ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
 #define MSM_PMEM_SIZE 0x4000000 /* 64 Mbytes */
@@ -141,10 +141,13 @@
 
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 #define MSM_PMEM_KERNEL_EBI1_SIZE  0xB0C000
-#define MSM_ION_SF_SIZE		0x2800000 /* (40MB) */
-#define MSM_ION_MM_SIZE		0x4000000 /* (64MB) */
+#define MSM_ION_SF_SIZE		MSM_PMEM_SIZE
+#define MSM_ION_MM_FW_SIZE	0x200000 /* (2MB) */
+#define MSM_ION_MM_SIZE		MSM_PMEM_ADSP_SIZE
+#define MSM_ION_QSECOM_SIZE	0x100000 /* (1MB) */
 #define MSM_ION_MFC_SIZE	SZ_8K
-#define MSM_ION_HEAP_NUM	5
+#define MSM_ION_AUDIO_SIZE	MSM_PMEM_AUDIO_SIZE
+#define MSM_ION_HEAP_NUM	8
 #define MSM_LIQUID_ION_MM_SIZE (MSM_ION_MM_SIZE + 0x600000)
 static unsigned int msm_ion_cp_mm_size = MSM_ION_MM_SIZE;
 #else
@@ -312,16 +315,24 @@
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 static struct ion_cp_heap_pdata cp_mm_ion_pdata = {
 	.permission_type = IPT_TYPE_MM_CARVEOUT,
+	.align = PAGE_SIZE,
 };
 
 static struct ion_cp_heap_pdata cp_mfc_ion_pdata = {
 	.permission_type = IPT_TYPE_MFC_SHAREDMEM,
+	.align = PAGE_SIZE,
 };
 
 static struct ion_co_heap_pdata co_ion_pdata = {
+	.adjacent_mem_id = INVALID_HEAP_ID,
+	.align = PAGE_SIZE,
+};
+
+static struct ion_co_heap_pdata fw_co_ion_pdata = {
+	.adjacent_mem_id = ION_CP_MM_HEAP_ID,
+	.align = SZ_128K,
 };
 #endif
-
 static struct ion_platform_data ion_pdata = {
 	.nr = MSM_ION_HEAP_NUM,
 	.heaps = {
@@ -337,7 +348,7 @@
 			.name	= ION_SF_HEAP_NAME,
 			.size	= MSM_ION_SF_SIZE,
 			.memory_type = ION_EBI_TYPE,
-			.extra_data = &co_ion_pdata,
+			.extra_data = (void *) &co_ion_pdata,
 		},
 		{
 			.id	= ION_CP_MM_HEAP_ID,
@@ -348,6 +359,14 @@
 			.extra_data = (void *) &cp_mm_ion_pdata,
 		},
 		{
+			.id	= ION_MM_FIRMWARE_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_MM_FIRMWARE_HEAP_NAME,
+			.size	= MSM_ION_MM_FW_SIZE,
+			.memory_type = ION_EBI_TYPE,
+			.extra_data = (void *) &fw_co_ion_pdata,
+		},
+		{
 			.id	= ION_CP_MFC_HEAP_ID,
 			.type	= ION_HEAP_TYPE_CP,
 			.name	= ION_MFC_HEAP_NAME,
@@ -360,6 +379,22 @@
 			.type	= ION_HEAP_TYPE_IOMMU,
 			.name	= ION_IOMMU_HEAP_NAME,
 		},
+		{
+			.id	= ION_QSECOM_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_QSECOM_HEAP_NAME,
+			.size	= MSM_ION_QSECOM_SIZE,
+			.memory_type = ION_EBI_TYPE,
+			.extra_data = (void *) &co_ion_pdata,
+		},
+		{
+			.id	= ION_AUDIO_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_AUDIO_HEAP_NAME,
+			.size	= MSM_ION_AUDIO_SIZE,
+			.memory_type = ION_EBI_TYPE,
+			.extra_data = (void *) &co_ion_pdata,
+		},
 #endif
 	}
 };
@@ -394,8 +429,11 @@
 		}
 	}
 	msm8960_reserve_table[MEMTYPE_EBI1].size += msm_ion_cp_mm_size;
+	msm8960_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MM_FW_SIZE;
 	msm8960_reserve_table[MEMTYPE_EBI1].size += MSM_ION_SF_SIZE;
 	msm8960_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MFC_SIZE;
+	msm8960_reserve_table[MEMTYPE_EBI1].size += MSM_ION_QSECOM_SIZE;
+	msm8960_reserve_table[MEMTYPE_EBI1].size += MSM_ION_AUDIO_SIZE;
 #endif
 }
 
diff --git a/arch/arm/mach-msm/board-copper.c b/arch/arm/mach-msm/board-copper.c
index a372eb6..f26187e 100644
--- a/arch/arm/mach-msm/board-copper.c
+++ b/arch/arm/mach-msm/board-copper.c
@@ -77,6 +77,8 @@
 	CLK_DUMMY("dfab_clk",	DFAB_CLK,	NULL, 0),
 	CLK_DUMMY("dma_bam_pclk",	DMA_BAM_P_CLK,	NULL, 0),
 	CLK_DUMMY("mem_clk",	NULL,	NULL, 0),
+	CLK_DUMMY("core_clk",	SPI_CLK,	"spi_qsd.1",	OFF),
+	CLK_DUMMY("iface_clk",	SPI_P_CLK,	"spi_qsd.1",	OFF),
 };
 
 struct clock_init_data msm_dummy_clock_init_data __initdata = {
@@ -89,6 +91,8 @@
 			"msm_serial_hsl.0", NULL),
 	OF_DEV_AUXDATA("qcom,hsusb-otg", 0xF9A55000, \
 			"msm_otg", NULL),
+	OF_DEV_AUXDATA("qcom,spi-qup-v2", 0xF9924000, \
+			"spi_qsd.1", NULL),
 	{}
 };
 
diff --git a/arch/arm/mach-msm/board-msm7627a-bt.c b/arch/arm/mach-msm/board-msm7627a-bt.c
index d4f06fa..8b3b606 100644
--- a/arch/arm/mach-msm/board-msm7627a-bt.c
+++ b/arch/arm/mach-msm/board-msm7627a-bt.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
@@ -677,11 +677,9 @@
 		pr_err("%s: could not enable regulator: %d\n", __func__, rc);
 		goto reg_fail;
 	}
-	if (machine_is_msm7627a_qrd1())
-		gpio_tlmm_config(GPIO_CFG(gpio_bt_sys_rest_en, 0,
-			GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
-			GPIO_CFG_2MA), GPIO_CFG_ENABLE);
-
+	gpio_tlmm_config(GPIO_CFG(gpio_bt_sys_rest_en, 0,
+				GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
+				GPIO_CFG_2MA), GPIO_CFG_ENABLE);
 
 	/*setup Bahama_sys_reset_n*/
 	rc = gpio_request(gpio_bt_sys_rest_en, "bahama sys_rst_n");
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index df04bb2..7699aa8 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -2672,12 +2672,13 @@
 
 #define MSM_ION_SF_SIZE		0x1800000 /* 24MB */
 #define MSM_ION_CAMERA_SIZE     MSM_PMEM_ADSP_SIZE
-#define MSM_ION_MM_SIZE		0x3800000 /* 56MB */
+#define MSM_ION_MM_FW_SIZE	0x200000 /* (2MB) */
+#define MSM_ION_MM_SIZE		0x3600000 /* (54MB) */
 #define MSM_ION_MFC_SIZE	SZ_8K
 #define MSM_ION_WB_SIZE		0x600000 /* 6MB */
 
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-#define MSM_ION_HEAP_NUM	6
+#define MSM_ION_HEAP_NUM	7
 #else
 #define MSM_ION_HEAP_NUM	1
 #endif
@@ -5242,6 +5243,7 @@
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
 static struct ion_cp_heap_pdata cp_mm_ion_pdata = {
 	.permission_type = IPT_TYPE_MM_CARVEOUT,
+	.align = PAGE_SIZE,
 	.request_region = request_smi_region,
 	.release_region = release_smi_region,
 	.setup_region = setup_smi_region,
@@ -5249,6 +5251,7 @@
 
 static struct ion_cp_heap_pdata cp_mfc_ion_pdata = {
 	.permission_type = IPT_TYPE_MFC_SHAREDMEM,
+	.align = PAGE_SIZE,
 	.request_region = request_smi_region,
 	.release_region = release_smi_region,
 	.setup_region = setup_smi_region,
@@ -5256,9 +5259,17 @@
 
 static struct ion_cp_heap_pdata cp_wb_ion_pdata = {
 	.permission_type = IPT_TYPE_MDP_WRITEBACK,
+	.align = PAGE_SIZE,
+};
+
+static struct ion_co_heap_pdata fw_co_ion_pdata = {
+	.adjacent_mem_id = ION_CP_MM_HEAP_ID,
+	.align = SZ_128K,
 };
 
 static struct ion_co_heap_pdata co_ion_pdata = {
+	.adjacent_mem_id = INVALID_HEAP_ID,
+	.align = PAGE_SIZE,
 };
 #endif
 static struct ion_platform_data ion_pdata = {
@@ -5276,7 +5287,7 @@
 			.name	= ION_SF_HEAP_NAME,
 			.size	= MSM_ION_SF_SIZE,
 			.memory_type = ION_EBI_TYPE,
-			.extra_data = &co_ion_pdata,
+			.extra_data = (void *)&co_ion_pdata,
 		},
 		{
 			.id	= ION_CP_MM_HEAP_ID,
@@ -5287,6 +5298,14 @@
 			.extra_data = (void *) &cp_mm_ion_pdata,
 		},
 		{
+			.id	= ION_MM_FIRMWARE_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_MM_FIRMWARE_HEAP_NAME,
+			.size	= MSM_ION_MM_FW_SIZE,
+			.memory_type = ION_SMI_TYPE,
+			.extra_data = (void *) &fw_co_ion_pdata,
+		},
+		{
 			.id	= ION_CAMERA_HEAP_ID,
 			.type	= ION_HEAP_TYPE_CARVEOUT,
 			.name	= ION_CAMERA_HEAP_NAME,
@@ -5353,6 +5372,7 @@
 {
 #if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
 	msm8x60_reserve_table[MEMTYPE_EBI1].size += MSM_ION_SF_SIZE;
+	msm8x60_reserve_table[MEMTYPE_SMI].size += MSM_ION_MM_FW_SIZE;
 	msm8x60_reserve_table[MEMTYPE_SMI].size += MSM_ION_MM_SIZE;
 	msm8x60_reserve_table[MEMTYPE_SMI].size += MSM_ION_MFC_SIZE;
 	msm8x60_reserve_table[MEMTYPE_EBI1].size += MSM_ION_CAMERA_SIZE;
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 295c7d9..68c5059 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -5313,6 +5313,13 @@
 	CLK_LOOKUP("core_clk",		gfx3d_clk.c,		"msm_iommu.9"),
 	CLK_LOOKUP("core_clk",		gfx2d0_clk.c,		"msm_iommu.10"),
 	CLK_LOOKUP("core_clk",		gfx2d1_clk.c,		"msm_iommu.11"),
+
+	CLK_LOOKUP("mdp_iommu_clk", mdp_axi_clk.c,	"msm_vidc.0"),
+	CLK_LOOKUP("rot_iommu_clk",	rot_axi_clk.c,	"msm_vidc.0"),
+	CLK_LOOKUP("vcodec_iommu0_clk", vcodec_axi_a_clk.c, "msm_vidc.0"),
+	CLK_LOOKUP("vcodec_iommu1_clk", vcodec_axi_b_clk.c, "msm_vidc.0"),
+	CLK_LOOKUP("smmu_iface_clk", smmu_p_clk.c,	"msm_vidc.0"),
+
 	CLK_LOOKUP("dfab_dsps_clk",	dfab_dsps_clk.c, NULL),
 	CLK_LOOKUP("core_clk",		dfab_usb_hs_clk.c,	"msm_otg"),
 	CLK_LOOKUP("bus_clk",		dfab_sdc1_clk.c, "msm_sdcc.1"),
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index c33daf7..3e57ebc 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -1671,6 +1671,11 @@
 	CLK_LOOKUP("core_clk",	     usb_hsic_sys_clk.c,       "msm_hsic_host"),
 	CLK_LOOKUP("iface_clk",	     usb_hsic_p_clk.c,	       "msm_hsic_host"),
 	CLK_LOOKUP("phy_clk",        usb_hsic_clk.c,	       "msm_hsic_host"),
+	CLK_LOOKUP("alt_core_clk",  usb_hsic_xcvr_clk.c, "msm_hsic_peripheral"),
+	CLK_LOOKUP("cal_clk",  usb_hsic_hsio_cal_clk.c,  "msm_hsic_peripheral"),
+	CLK_LOOKUP("core_clk",      usb_hsic_sys_clk.c,  "msm_hsic_peripheral"),
+	CLK_LOOKUP("iface_clk",     usb_hsic_p_clk.c,    "msm_hsic_peripheral"),
+	CLK_LOOKUP("phy_clk",       usb_hsic_clk.c,      "msm_hsic_peripheral"),
 
 	CLK_LOOKUP("iface_clk",		sdc1_p_clk.c,		"msm_sdcc.1"),
 	CLK_LOOKUP("iface_clk",		sdc2_p_clk.c,		"msm_sdcc.2"),
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 12a00e6..9c77f3d 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -24,6 +24,7 @@
 #include <mach/dma.h>
 #include <sound/msm-dai-q6.h>
 #include <sound/apr_audio.h>
+#include <mach/msm_bus_board.h>
 #include "clock.h"
 #include "devices.h"
 #include "msm_watchdog.h"
@@ -694,6 +695,27 @@
 	},
 };
 
+struct platform_device msm_bus_8064_sys_fabric = {
+	.name  = "msm_bus_fabric",
+	.id    =  MSM_BUS_FAB_SYSTEM,
+};
+struct platform_device msm_bus_8064_apps_fabric = {
+	.name  = "msm_bus_fabric",
+	.id    = MSM_BUS_FAB_APPSS,
+};
+struct platform_device msm_bus_8064_mm_fabric = {
+	.name  = "msm_bus_fabric",
+	.id    = MSM_BUS_FAB_MMSS,
+};
+struct platform_device msm_bus_8064_sys_fpb = {
+	.name  = "msm_bus_fabric",
+	.id    = MSM_BUS_FAB_SYSTEM_FPB,
+};
+struct platform_device msm_bus_8064_cpss_fpb = {
+	.name  = "msm_bus_fabric",
+	.id    = MSM_BUS_FAB_CPSS_FPB,
+};
+
 static struct msm_sps_platform_data msm_sps_pdata = {
 	.bamdma_restricted_pipes = 0x06,
 };
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 33a543d..5d28fa9 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -264,3 +264,9 @@
 extern struct platform_device msm_funnel_device;
 extern struct platform_device msm_ptm_device;
 #endif
+
+extern struct platform_device msm_bus_8064_apps_fabric;
+extern struct platform_device msm_bus_8064_sys_fabric;
+extern struct platform_device msm_bus_8064_mm_fabric;
+extern struct platform_device msm_bus_8064_sys_fpb;
+extern struct platform_device msm_bus_8064_cpss_fpb;
diff --git a/arch/arm/mach-msm/idle_stats_device.c b/arch/arm/mach-msm/idle_stats_device.c
index 5c4b6a3..c28cf94 100644
--- a/arch/arm/mach-msm/idle_stats_device.c
+++ b/arch/arm/mach-msm/idle_stats_device.c
@@ -137,8 +137,7 @@
 		device->stats = &device->stats_vector[1];
 	else
 		device->stats = &device->stats_vector[0];
-	device->stats->event = (stats->event &
-			MSM_IDLE_STATS_EVENT_BUSY_TIMER_EXPIRED);
+	device->stats->event = 0;
 	device->stats->nr_collected = 0;
 	spin_unlock(&device->lock);
 	if (stats->nr_collected >= MSM_IDLE_STATS_NR_MAX_INTERVALS) {
@@ -217,7 +216,7 @@
 		device->remaining_time =
 				hrtimer_get_remaining(&device->busy_timer);
 		if (ktime_to_us(device->remaining_time) <= 0)
-			device->remaining_time = us_to_ktime(1);
+			device->remaining_time = us_to_ktime(0);
 	} else {
 		device->remaining_time = us_to_ktime(0);
 	}
@@ -228,8 +227,11 @@
 void msm_idle_stats_idle_end(struct msm_idle_stats_device *device,
 				struct msm_idle_pulse *pulse)
 {
+	u32 idle_time = 0;
 	spin_lock(&device->lock);
 	if (ktime_to_us(device->idle_start) != 0) {
+		idle_time = ktime_to_us(ktime_get())
+			- ktime_to_us(device->idle_start);
 		device->idle_start = us_to_ktime(0);
 	    msm_idle_stats_add_sample(device, pulse);
 		if (device->stats->event &
@@ -240,7 +242,10 @@
 				MSM_IDLE_STATS_EVENT_BUSY_TIMER_EXPIRED_RESET);
 		} else if (ktime_to_us(device->busy_timer_interval) > 0) {
 			ktime_t busy_timer = device->busy_timer_interval;
-			if ((pulse->wait_interval > 0) &&
+			/* if it is serialized, it would be full busy,
+			 * checking 80%
+			 */
+			if ((pulse->wait_interval*5 >= idle_time*4) &&
 				(ktime_to_us(device->remaining_time) > 0) &&
 				(ktime_to_us(device->remaining_time) <
 				 ktime_to_us(busy_timer)))
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8064.h b/arch/arm/mach-msm/include/mach/msm_iomap-8064.h
index 7f5bd75..15b2856 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8064.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8064.h
@@ -77,4 +77,25 @@
 #define APQ8064_IMEM_PHYS		0x2A03F000
 #define APQ8064_IMEM_SIZE		SZ_4K
 
+#define APQ8064_RPM_PHYS		0x00108000
+#define APQ8064_RPM_SIZE		SZ_4K
+
+#define APQ8064_RPM_MPM_PHYS		0x00200000
+#define APQ8064_RPM_MPM_SIZE		SZ_4K
+
+#define APQ8064_SAW0_PHYS		0x02089000
+#define APQ8064_SAW0_SIZE		SZ_4K
+
+#define APQ8064_SAW1_PHYS		0x02099000
+#define APQ8064_SAW1_SIZE		SZ_4K
+
+#define APQ8064_SAW2_PHYS		0x020A9000
+#define APQ8064_SAW2_SIZE		SZ_4K
+
+#define APQ8064_SAW3_PHYS		0x020B9000
+#define APQ8064_SAW3_SIZE		SZ_4K
+
+#define APQ8064_SAW_L2_PHYS		0x02012000
+#define APQ8064_SAW_L2_SIZE		SZ_4K
+
 #endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h
index dd01c62..ff0b368 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -75,8 +75,10 @@
 #define MSM_RPM_BASE		IOMEM(0xFA801000)	/*  4K	*/
 #define MSM_RPM_MPM_BASE	IOMEM(0xFA802000)	/*  4K	*/
 #define MSM_QFPROM_BASE		IOMEM(0xFA700000)	/*  4K  */
-#define MSM_L2CC_BASE		IOMEM(0xFA701000)	/* 4K */
-#define MSM_APCS_GLB_BASE	IOMEM(0xFA702000)	/* 4K */
+#define MSM_L2CC_BASE		IOMEM(0xFA701000)	/*  4K  */
+#define MSM_APCS_GLB_BASE	IOMEM(0xFA702000)	/*  4K  */
+#define MSM_SAW2_BASE		IOMEM(0xFA703000)	/*  4k  */
+#define MSM_SAW3_BASE		IOMEM(0xFA704000)	/*  4k  */
 
 #if defined(CONFIG_ARCH_MSM9615)
 #define MSM_SHARED_RAM_SIZE	SZ_1M
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index 2d5b0a4..9622a4c 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -265,6 +265,13 @@
 	MSM_CHIP_DEVICE(MMSS_CLK_CTL, APQ8064),
 	MSM_CHIP_DEVICE(LPASS_CLK_CTL, APQ8064),
 	MSM_CHIP_DEVICE(APCS_GCC, APQ8064),
+	MSM_CHIP_DEVICE(RPM, APQ8064),
+	MSM_CHIP_DEVICE(RPM_MPM, APQ8064),
+	MSM_CHIP_DEVICE(SAW0, APQ8064),
+	MSM_CHIP_DEVICE(SAW1, APQ8064),
+	MSM_CHIP_DEVICE(SAW2, APQ8064),
+	MSM_CHIP_DEVICE(SAW3, APQ8064),
+	MSM_CHIP_DEVICE(SAW_L2, APQ8064),
 	MSM_CHIP_DEVICE(IMEM, APQ8064),
 	{
 		.virtual =  (unsigned long) MSM_SHARED_RAM_BASE,
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index d73d4a0..f1c6c48 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -31,13 +31,8 @@
 
 int pen_release = -1;
 
-/* Initialize the present map (cpu_set(i, cpu_present_map)). */
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
 {
-	int i;
-
-	for (i = 0; i < max_cpus; i++)
-		cpu_set(i, cpu_present_map);
 }
 
 void __init smp_init_cpus(void)
diff --git a/arch/arm/mach-msm/sdio_al_test.c b/arch/arm/mach-msm/sdio_al_test.c
index a71aae3..c97588f 100644
--- a/arch/arm/mach-msm/sdio_al_test.c
+++ b/arch/arm/mach-msm/sdio_al_test.c
@@ -146,7 +146,6 @@
 	SDIO_DIAG,
 	SDIO_DUN,
 	SDIO_SMEM,
-	SDIO_CIQ,
 	SDIO_CSVT,
 	SDIO_MAX_CHANNELS
 };
@@ -250,7 +249,7 @@
 	struct dentry *rpc_sender_rmnet_a2_perf_test;
 	struct dentry *all_channels_test;
 	struct dentry *host_sender_no_lp_diag_test;
-	struct dentry *host_sender_no_lp_diag_rpc_ciq_test;
+	struct dentry *host_sender_no_lp_diag_rpc_test;
 	struct dentry *rmnet_small_packets_test;
 	struct dentry *rmnet_rtt_test;
 	struct dentry *csvt_rtt_test;
@@ -297,7 +296,6 @@
 	u8 *smem_buf;
 	uint32_t smem_counter;
 
-	struct platform_device *ciq_app_pdev;
 	struct platform_device *csvt_app_pdev;
 
 	wait_queue_head_t   wait_q;
@@ -1181,7 +1179,6 @@
 		set_params_a2_perf(test_ctx->test_ch_arr[SDIO_RMNT]);
 		set_params_a2_perf(test_ctx->test_ch_arr[SDIO_DUN]);
 		set_params_smem_test(test_ctx->test_ch_arr[SDIO_SMEM]);
-		set_params_loopback_9k(test_ctx->test_ch_arr[SDIO_CIQ]);
 		set_params_a2_perf(test_ctx->test_ch_arr[SDIO_CSVT]);
 
 		ret = test_start();
@@ -1284,8 +1281,8 @@
 	.read = host_sender_no_lp_diag_test_read,
 };
 
-/* HOST SENDER NO LP DIAG, RPC, CIQ TEST */
-static ssize_t host_sender_no_lp_diag_rpc_ciq_test_write(
+/* HOST SENDER NO LP DIAG, RPC TEST */
+static ssize_t host_sender_no_lp_diag_rpc_test_write(
 						 struct file *file,
 						 const char __user *buf,
 						 size_t count,
@@ -1295,8 +1292,8 @@
 	int i = 0;
 	int number = -1;
 
-	pr_info(TEST_MODULE_NAME "-- HOST SENDER NO LP FOR DIAG, RPC, "
-		"CIQ TEST --");
+	pr_info(TEST_MODULE_NAME "-- HOST SENDER NO LP FOR DIAG, RPC "
+		"TEST --");
 
 	number = sdio_al_test_extract_number(buf, count);
 
@@ -1313,7 +1310,6 @@
 		sdio_al_test_initial_dev_and_chan(test_ctx);
 
 		set_params_8k_sender_no_lp(test_ctx->test_ch_arr[SDIO_DIAG]);
-		set_params_8k_sender_no_lp(test_ctx->test_ch_arr[SDIO_CIQ]);
 		set_params_8k_sender_no_lp(test_ctx->test_ch_arr[SDIO_RPC]);
 
 		ret = test_start();
@@ -1325,7 +1321,7 @@
 	return count;
 }
 
-static ssize_t host_sender_no_lp_diag_rpc_ciq_test_read(
+static ssize_t host_sender_no_lp_diag_rpc_test_read(
 						 struct file *file,
 						 char __user *buffer,
 						 size_t count,
@@ -1334,7 +1330,7 @@
 	memset((void *)buffer, 0, count);
 
 	snprintf(buffer, count,
-		 "\nHOST_SENDER_NO_LP_DIAG_RPC_CIQ_TEST\n"
+		 "\nHOST_SENDER_NO_LP_DIAG_RPC_TEST\n"
 		 "===================================\n"
 		 "Description:\n"
 		 "TBD\n");
@@ -1347,10 +1343,10 @@
 	}
 }
 
-const struct file_operations host_sender_no_lp_diag_rpc_ciq_test_ops = {
+const struct file_operations host_sender_no_lp_diag_rpc_test_ops = {
 	.open = sdio_al_test_open,
-	.write = host_sender_no_lp_diag_rpc_ciq_test_write,
-	.read = host_sender_no_lp_diag_rpc_ciq_test_read,
+	.write = host_sender_no_lp_diag_rpc_test_write,
+	.read = host_sender_no_lp_diag_rpc_test_read,
 };
 
 /* RMNET SMALL PACKETS TEST */
@@ -1774,7 +1770,6 @@
 
 		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RMNT]);
 		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DUN]);
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_CIQ]);
 
 		ret = test_start();
 
@@ -1844,7 +1839,6 @@
 		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DIAG]);
 		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RMNT]);
 		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DUN]);
-		set_params_modem_reset(test_ctx->test_ch_arr[SDIO_CIQ]);
 
 		ret = test_start();
 
@@ -1910,7 +1904,6 @@
 		sdio_al_test_initial_dev_and_chan(test_ctx);
 
 		set_params_loopback_9k_close(ch_arr[SDIO_DIAG]);
-		set_params_loopback_9k_close(ch_arr[SDIO_CIQ]);
 		set_params_loopback_9k_close(ch_arr[SDIO_RPC]);
 		set_params_loopback_9k_close(ch_arr[SDIO_SMEM]);
 		set_params_loopback_9k_close(ch_arr[SDIO_QMI]);
@@ -1924,9 +1917,8 @@
 			break;
 
 		pr_info(TEST_MODULE_NAME " -- correctness test for"
-				"DIAG, CIQ ");
+				"DIAG ");
 		set_params_loopback_9k(ch_arr[SDIO_DIAG]);
-		set_params_loopback_9k(ch_arr[SDIO_CIQ]);
 
 		ret = test_start();
 
@@ -1950,7 +1942,7 @@
 		 "Description:\n"
 		 "In this test the host sends 5k packets to the modem in the "
 		 "following sequence: Send a random burst of packets on "
-		 "Diag, CIQ and Rmnet channels, read 0 or a random number "
+		 "Diag and Rmnet channels, read 0 or a random number "
 		 "of packets, close and re-open the channel. At the end of the "
 		 "test, the channel is verified by running a loopback test\n\n"
 		 "END OF DESCRIPTION\n");
@@ -2373,8 +2365,6 @@
 
 		set_params_lpm_test(test_ctx->test_ch_arr[SDIO_RPC],
 				    SDIO_TEST_LPM_RANDOM, 0);
-		set_params_lpm_test(test_ctx->test_ch_arr[SDIO_CIQ],
-				    SDIO_TEST_LPM_RANDOM, 0);
 		set_params_lpm_test(test_ctx->test_ch_arr[SDIO_DIAG],
 				    SDIO_TEST_LPM_RANDOM, 0);
 		set_params_lpm_test(test_ctx->test_ch_arr[SDIO_QMI],
@@ -2403,7 +2393,7 @@
 		 "Description:\n"
 		 "In this test, the HOST and CLIENT "
 		 "send messages to each other,\n"
-		 "random in time, over RPC, QMI, DIAG AND CIQ channels\n"
+		 "random in time, over RPC, QMI AND DIAG channels\n"
 		 "(i.e, on both SDIO devices).\n"
 		 "All events are being recorded, and later on,\n"
 		 "they are being analysed by the HOST and by the CLIENT,\n"
@@ -2545,12 +2535,12 @@
 				    NULL,
 				    &host_sender_no_lp_diag_test_ops);
 
-	test_ctx->debug.host_sender_no_lp_diag_rpc_ciq_test =
-		debugfs_create_file("170_host_sender_no_lp_diag_rpc_ciq_test",
+	test_ctx->debug.host_sender_no_lp_diag_rpc_test =
+		debugfs_create_file("170_host_sender_no_lp_diag_rpc_test",
 				     S_IRUGO | S_IWUGO,
 				     test_ctx->debug.debug_root,
 				     NULL,
-				     &host_sender_no_lp_diag_rpc_ciq_test_ops);
+				     &host_sender_no_lp_diag_rpc_test_ops);
 
 	test_ctx->debug.rmnet_small_packets_test =
 		debugfs_create_file("180_rmnet_small_packets_test",
@@ -2697,9 +2687,6 @@
 	else if (!strncmp(name, "SDIO_SMEM_TEST",
 			  strnlen("SDIO_SMEM_TEST", TEST_CH_NAME_SIZE)))
 		return SDIO_SMEM;
-	else if (!strncmp(name, "SDIO_CIQ_TEST",
-			  strnlen("SDIO_CIQ_TEST", TEST_CH_NAME_SIZE)))
-		return SDIO_CIQ;
 	else if (!strncmp(name, "SDIO_CSVT_TEST",
 			  strnlen("SDIO_CSVT_TEST", TEST_CH_NAME_SIZE)))
 		return SDIO_CSVT;
@@ -5829,7 +5816,6 @@
 	case SDIO_RPC:
 		tch->packet_length = 128; /* max is 2K*/
 		break;
-	case SDIO_CIQ:
 	case SDIO_DIAG:
 	case SDIO_RMNT:
 	default:
@@ -6297,34 +6283,6 @@
 
 }
 
-static int sdio_test_channel_ciq_probe(struct platform_device *pdev)
-{
-	int ret = 0;
-
-	if (!pdev)
-		return -ENODEV;
-
-	test_ctx->ciq_app_pdev = platform_device_alloc("SDIO_CIQ_TEST_APP", -1);
-	ret = platform_device_add(test_ctx->ciq_app_pdev);
-		if (ret) {
-			pr_err(MODULE_NAME ":platform_device_add failed, "
-					   "ret=%d\n", ret);
-			return ret;
-		}
-
-	return sdio_test_channel_probe(pdev);
-}
-
-static int sdio_test_channel_ciq_remove(struct platform_device *pdev)
-{
-	if (!pdev)
-		return -ENODEV;
-
-	platform_device_unregister(test_ctx->ciq_app_pdev);
-
-	return sdio_test_channel_remove(pdev);
-}
-
 static int sdio_test_channel_csvt_probe(struct platform_device *pdev)
 {
 	int ret = 0;
@@ -6408,15 +6366,6 @@
 	},
 };
 
-static struct platform_driver sdio_ciq_drv = {
-	.probe		= sdio_test_channel_ciq_probe,
-	.remove		= sdio_test_channel_ciq_remove,
-	.driver		= {
-		.name	= "SDIO_CIQ_TEST",
-		.owner	= THIS_MODULE,
-	},
-};
-
 static struct platform_driver sdio_csvt_drv = {
 	.probe		= sdio_test_channel_csvt_probe,
 	.remove		= sdio_test_channel_csvt_remove,
@@ -6494,7 +6443,6 @@
 	platform_driver_register(&sdio_smem_drv);
 	platform_driver_register(&sdio_rmnt_drv);
 	platform_driver_register(&sdio_dun_drv);
-	platform_driver_register(&sdio_ciq_drv);
 	platform_driver_register(&sdio_csvt_drv);
 
 	return ret;
@@ -6523,7 +6471,6 @@
 	platform_driver_unregister(&sdio_smem_drv);
 	platform_driver_unregister(&sdio_rmnt_drv);
 	platform_driver_unregister(&sdio_dun_drv);
-	platform_driver_unregister(&sdio_ciq_drv);
 	platform_driver_unregister(&sdio_csvt_drv);
 
 	for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
diff --git a/arch/arm/mach-msm/sdio_tty.c b/arch/arm/mach-msm/sdio_tty.c
index 2aaa41e..41bc270 100644
--- a/arch/arm/mach-msm/sdio_tty.c
+++ b/arch/arm/mach-msm/sdio_tty.c
@@ -30,11 +30,6 @@
 #define MAX_SDIO_TTY_DEV_NAME_SIZE	25
 
 /* Configurations per channel device */
-/* CIQ */
-#define SDIO_TTY_CIQ_DEV		"sdio_tty_ciq_0"
-#define SDIO_TTY_CIQ_TEST_DEV		"sdio_tty_ciq_test_0"
-#define SDIO_TTY_CH_CIQ			"SDIO_CIQ"
-
 /* CSVT */
 #define SDIO_TTY_CSVT_DEV		"sdio_tty_csvt_0"
 #define SDIO_TTY_CSVT_TEST_DEV		"sdio_tty_csvt_test_0"
@@ -48,15 +43,11 @@
 };
 
 enum sdio_tty_devices {
-	SDIO_CIQ,
-	SDIO_CIQ_TEST_APP,
 	SDIO_CSVT,
 	SDIO_CSVT_TEST_APP,
 };
 
 static const struct platform_device_id sdio_tty_id_table[] = {
-	{ "SDIO_CIQ",		SDIO_CIQ },
-	{ "SDIO_CIQ_TEST_APP",	SDIO_CIQ_TEST_APP },
 	{ "SDIO_CSVT",		SDIO_CSVT },
 	{ "SDIO_CSVT_TEST_APP",	SDIO_CSVT_TEST_APP },
 	{ },
@@ -95,8 +86,6 @@
  * Enable sdio_tty debug messages
  * By default the sdio_tty debug messages are turned off
  */
-static int ciq_debug_msg_on;
-module_param(ciq_debug_msg_on, int, 0);
 static int csvt_debug_msg_on;
 module_param(csvt_debug_msg_on, int, 0);
 
@@ -677,16 +666,6 @@
 	pr_debug(SDIO_TTY_MODULE_NAME ": %s for %s", __func__, pdev->name);
 
 	switch (device_id) {
-	case SDIO_CIQ:
-		device_name = SDIO_TTY_CIQ_DEV;
-		channel_name = SDIO_TTY_CH_CIQ;
-		debug_msg_on = ciq_debug_msg_on;
-		break;
-	case SDIO_CIQ_TEST_APP:
-		device_name = SDIO_TTY_CIQ_TEST_DEV;
-		channel_name = SDIO_TTY_CH_CIQ;
-		debug_msg_on = ciq_debug_msg_on;
-		break;
 	case SDIO_CSVT:
 		device_name = SDIO_TTY_CSVT_DEV;
 		channel_name = SDIO_TTY_CH_CSVT;
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index ecfe93c..ce65e93 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -125,14 +125,6 @@
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
 {
-	int i;
-
-	/*
-	 * Initialise the present map, which describes the set of CPUs
-	 * actually populated at the present time.
-	 */
-	for (i = 0; i < max_cpus; i++)
-		set_cpu_present(i, true);
 
 	/*
 	 * Initialise the SCU and wake up the secondary core using
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
index 963bf0d..4ae943b 100644
--- a/arch/arm/mach-realview/platsmp.c
+++ b/arch/arm/mach-realview/platsmp.c
@@ -68,14 +68,6 @@
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
 {
-	int i;
-
-	/*
-	 * Initialise the present map, which describes the set of CPUs
-	 * actually populated at the present time.
-	 */
-	for (i = 0; i < max_cpus; i++)
-		set_cpu_present(i, true);
 
 	scu_enable(scu_base_addr());
 
diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c
index f3888fe..66f9806 100644
--- a/arch/arm/mach-shmobile/platsmp.c
+++ b/arch/arm/mach-shmobile/platsmp.c
@@ -64,10 +64,5 @@
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
 {
-	int i;
-
-	for (i = 0; i < max_cpus; i++)
-		set_cpu_present(i, true);
-
 	shmobile_smp_prepare_cpus();
 }
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index b8ae3c9..1a594dc 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -129,14 +129,6 @@
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
 {
-	int i;
-
-	/*
-	 * Initialise the present map, which describes the set of CPUs
-	 * actually populated at the present time.
-	 */
-	for (i = 0; i < max_cpus; i++)
-		set_cpu_present(i, true);
 
 	scu_enable(scu_base);
 }
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c
index 0c527fe..a33df5f 100644
--- a/arch/arm/mach-ux500/platsmp.c
+++ b/arch/arm/mach-ux500/platsmp.c
@@ -172,14 +172,6 @@
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
 {
-	int i;
-
-	/*
-	 * Initialise the present map, which describes the set of CPUs
-	 * actually populated at the present time.
-	 */
-	for (i = 0; i < max_cpus; i++)
-		set_cpu_present(i, true);
 
 	scu_enable(scu_base_addr());
 	wakeup_secondary();
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index 765a71f..bfd32f5 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -229,10 +229,6 @@
 
 static void ct_ca9x4_smp_enable(unsigned int max_cpus)
 {
-	int i;
-	for (i = 0; i < max_cpus; i++)
-		set_cpu_present(i, true);
-
 	scu_enable(MMIO_P2V(A9_MPCORE_SCU));
 }
 #endif
diff --git a/drivers/char/msm_rotator.c b/drivers/char/msm_rotator.c
index 529d9dd..bd48925 100644
--- a/drivers/char/msm_rotator.c
+++ b/drivers/char/msm_rotator.c
@@ -569,11 +569,18 @@
 			      unsigned int in_paddr,
 			      unsigned int out_paddr,
 			      unsigned int use_imem,
-			      int new_session)
+			      int new_session,
+			      unsigned int out_chroma_paddr)
 {
 	int bpp;
+	uint32_t dst_format;
 
-	if (info->src.format != info->dst.format)
+	if (info->src.format == MDP_YCRYCB_H2V1)
+		dst_format = MDP_Y_CRCB_H2V1;
+	else
+		return -EINVAL;
+
+	if (info->dst.format != dst_format)
 		return -EINVAL;
 
 	bpp = get_bpp(info->src.format);
@@ -584,15 +591,25 @@
 	iowrite32(out_paddr +
 			((info->dst_y * info->dst.width) + info->dst_x),
 		  MSM_ROTATOR_OUTP0_ADDR);
+	iowrite32(out_chroma_paddr +
+			((info->dst_y * info->dst.width)/2 + info->dst_x),
+		  MSM_ROTATOR_OUTP1_ADDR);
 
 	if (new_session) {
-		iowrite32(info->src.width,
+		iowrite32(info->src.width * bpp,
 			  MSM_ROTATOR_SRC_YSTRIDE1);
-		iowrite32(info->dst.width,
-			  MSM_ROTATOR_OUT_YSTRIDE1);
+		if (info->rotations & MDP_ROT_90)
+			iowrite32(info->dst.width |
+				  (info->dst.width*2) << 16,
+				  MSM_ROTATOR_OUT_YSTRIDE1);
+		else
+			iowrite32(info->dst.width |
+				  (info->dst.width) << 16,
+				  MSM_ROTATOR_OUT_YSTRIDE1);
+
 		iowrite32(GET_PACK_PATTERN(CLR_Y, CLR_CR, CLR_Y, CLR_CB, 8),
 			  MSM_ROTATOR_SRC_UNPACK_PATTERN1);
-		iowrite32(GET_PACK_PATTERN(CLR_Y, CLR_CR, CLR_Y, CLR_CB, 8),
+		iowrite32(GET_PACK_PATTERN(0, 0, CLR_CR, CLR_CB, 8),
 			  MSM_ROTATOR_OUT_PACK_PATTERN1);
 		iowrite32((1  << 18) | 		/* chroma sampling 1=H2V1 */
 			  (ROTATIONS_TO_BITMASK(info->rotations) << 9) |
@@ -1036,7 +1053,8 @@
 	case MDP_YCRYCB_H2V1:
 		rc = msm_rotator_ycrycb(msm_rotator_dev->img_info[s],
 				in_paddr, out_paddr, use_imem,
-				msm_rotator_dev->last_session_idx != s);
+				msm_rotator_dev->last_session_idx != s,
+				out_chroma_paddr);
 		break;
 	default:
 		rc = -EINVAL;
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 4168c88..c44cde8 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -2,3 +2,6 @@
 config CLKDEV_LOOKUP
 	bool
 	select HAVE_CLK
+
+config HAVE_CLK_PREPARE
+	bool
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index d436ef4..34145fe 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -77,7 +77,7 @@
 	struct rb_root handles;
 	struct mutex lock;
 	unsigned int heap_mask;
-	const char *name;
+	char *name;
 	struct task_struct *task;
 	pid_t pid;
 	struct dentry *debug_root;
@@ -365,6 +365,11 @@
 	struct ion_device *dev = client->dev;
 	struct ion_buffer *buffer = NULL;
 	unsigned long secure_allocation = flags & ION_SECURE;
+	const unsigned int MAX_DBG_STR_LEN = 64;
+	char dbg_str[MAX_DBG_STR_LEN];
+	unsigned int dbg_str_idx = 0;
+
+	dbg_str[0] = '\0';
 
 	/*
 	 * traverse the list of heaps available in this system in priority
@@ -387,11 +392,31 @@
 		buffer = ion_buffer_create(heap, dev, len, align, flags);
 		if (!IS_ERR_OR_NULL(buffer))
 			break;
+		if (dbg_str_idx < MAX_DBG_STR_LEN) {
+			unsigned int len_left = MAX_DBG_STR_LEN-dbg_str_idx-1;
+			int ret_value = snprintf(&dbg_str[dbg_str_idx],
+						len_left, "%s ", heap->name);
+			if (ret_value >= len_left) {
+				/* overflow */
+				dbg_str[MAX_DBG_STR_LEN-1] = '\0';
+				dbg_str_idx = MAX_DBG_STR_LEN;
+			} else if (ret_value >= 0) {
+				dbg_str_idx += ret_value;
+			} else {
+				/* error */
+				dbg_str[MAX_DBG_STR_LEN-1] = '\0';
+			}
+		}
 	}
 	mutex_unlock(&dev->lock);
 
-	if (IS_ERR_OR_NULL(buffer))
+	if (IS_ERR_OR_NULL(buffer)) {
+		pr_debug("ION is unable to allocate 0x%x bytes (alignment: "
+			 "0x%x) from heap(s) %sfor client %s with heap "
+			 "mask 0x%x\n",
+			len, align, dbg_str, client->name, client->heap_mask);
 		return ERR_PTR(PTR_ERR(buffer));
+	}
 
 	handle = ion_handle_create(client, buffer);
 
@@ -984,6 +1009,7 @@
 	struct rb_node *parent = NULL;
 	struct ion_client *entry;
 	pid_t pid;
+	unsigned int name_len = strnlen(name, 64);
 
 	get_task_struct(current->group_leader);
 	task_lock(current->group_leader);
@@ -1017,7 +1043,17 @@
 	client->dev = dev;
 	client->handles = RB_ROOT;
 	mutex_init(&client->lock);
-	client->name = name;
+
+	client->name = kzalloc(sizeof(name_len+1), GFP_KERNEL);
+	if (!client->name) {
+		put_task_struct(current->group_leader);
+		kfree(client);
+		return ERR_PTR(-ENOMEM);
+	} else {
+		strncpy(client->name, name, name_len);
+		client->name[name_len] = '\0';
+	}
+
 	client->heap_mask = heap_mask;
 	client->task = task;
 	client->pid = pid;
@@ -1083,6 +1119,7 @@
 	debugfs_remove_recursive(client->debug_root);
 	mutex_unlock(&dev->lock);
 
+	kfree(client->name);
 	kfree(client);
 }
 
@@ -1568,30 +1605,8 @@
 		seq_printf(s, "%16.s %16u %16x\n", client->name, client->pid,
 			   size);
 	}
-	if (heap->ops->get_allocated) {
-		seq_printf(s, "total bytes currently allocated: %lx\n",
-			heap->ops->get_allocated(heap));
-	}
-	if (heap->ops->get_total) {
-		seq_printf(s, "total heap size: %lx\n",
-			heap->ops->get_total(heap));
-	}
-	if (heap->ops->get_alloc_cnt) {
-		seq_printf(s, "allocation count: %lx\n",
-			heap->ops->get_alloc_cnt(heap));
-	}
-	if (heap->ops->get_umap_cnt) {
-		seq_printf(s, "umapping count: %lx\n",
-			heap->ops->get_umap_cnt(heap));
-	}
-	if (heap->ops->get_kmap_cnt) {
-		seq_printf(s, "kmapping count: %lx\n",
-			heap->ops->get_kmap_cnt(heap));
-	}
-	if (heap->ops->get_secured) {
-		seq_printf(s, "secured heap: %s\n",
-			heap->ops->get_secured(heap) ? "Yes" : "No");
-	}
+	if (heap->ops->print_debug)
+		heap->ops->print_debug(heap, s);
 	return 0;
 }
 
diff --git a/drivers/gpu/ion/ion_carveout_heap.c b/drivers/gpu/ion/ion_carveout_heap.c
index 1c35f5c..ad0c7b1 100644
--- a/drivers/gpu/ion/ion_carveout_heap.c
+++ b/drivers/gpu/ion/ion_carveout_heap.c
@@ -25,6 +25,7 @@
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/iommu.h>
+#include <linux/seq_file.h>
 #include "ion_priv.h"
 
 #include <mach/iommu_domains.h>
@@ -131,28 +132,55 @@
 		vfree(buffer->sglist);
 }
 
+static int ion_carveout_request_region(struct ion_carveout_heap *carveout_heap)
+{
+	int ret_value = 0;
+	if (atomic_inc_return(&carveout_heap->map_count) == 1) {
+		if (carveout_heap->request_region) {
+			ret_value = carveout_heap->request_region(
+						carveout_heap->bus_id);
+			if (ret_value) {
+				pr_err("Unable to request SMI region");
+				atomic_dec(&carveout_heap->map_count);
+			}
+		}
+	}
+	return ret_value;
+}
+
+static int ion_carveout_release_region(struct ion_carveout_heap *carveout_heap)
+{
+	int ret_value = 0;
+	if (atomic_dec_and_test(&carveout_heap->map_count)) {
+		if (carveout_heap->release_region) {
+			ret_value = carveout_heap->release_region(
+						carveout_heap->bus_id);
+			if (ret_value)
+				pr_err("Unable to release SMI region");
+		}
+	}
+	return ret_value;
+}
+
 void *ion_carveout_heap_map_kernel(struct ion_heap *heap,
 				   struct ion_buffer *buffer,
 				   unsigned long flags)
 {
 	struct ion_carveout_heap *carveout_heap =
 		container_of(heap, struct ion_carveout_heap, heap);
+	void *ret_value;
 
-	if (atomic_inc_return(&carveout_heap->map_count) == 1) {
-		if (carveout_heap->request_region) {
-			int ret = carveout_heap->request_region(
-						carveout_heap->bus_id);
-			if (ret) {
-				pr_err("Unable to request SMI region");
-				atomic_dec(&carveout_heap->map_count);
-				return NULL;
-			}
-		}
-	}
+	if (ion_carveout_request_region(carveout_heap))
+		return NULL;
+
 	if (ION_IS_CACHED(flags))
-		return ioremap_cached(buffer->priv_phys, buffer->size);
+		ret_value = ioremap_cached(buffer->priv_phys, buffer->size);
 	else
-		return ioremap(buffer->priv_phys, buffer->size);
+		ret_value = ioremap(buffer->priv_phys, buffer->size);
+
+	if (!ret_value)
+		ion_carveout_release_region(carveout_heap);
+	return ret_value;
 }
 
 void ion_carveout_heap_unmap_kernel(struct ion_heap *heap,
@@ -164,15 +192,7 @@
 	__arch_iounmap(buffer->vaddr);
 	buffer->vaddr = NULL;
 
-	if (atomic_dec_and_test(&carveout_heap->map_count)) {
-		if (carveout_heap->release_region) {
-			int ret = carveout_heap->release_region(
-						carveout_heap->bus_id);
-			if (ret)
-				pr_err("Unable to release SMI region");
-		}
-	}
-
+	ion_carveout_release_region(carveout_heap);
 	return;
 }
 
@@ -181,29 +201,25 @@
 {
 	struct ion_carveout_heap *carveout_heap =
 		container_of(heap, struct ion_carveout_heap, heap);
+	int ret_value = 0;
 
-	if (atomic_inc_return(&carveout_heap->map_count) == 1) {
-		if (carveout_heap->request_region) {
-			int ret = carveout_heap->request_region(
-						carveout_heap->bus_id);
-			if (ret) {
-				pr_err("Unable to request SMI region");
-				atomic_dec(&carveout_heap->map_count);
-				return -EINVAL;
-			}
-		}
-	}
+	if (ion_carveout_request_region(carveout_heap))
+		return -EINVAL;
 
 	if (ION_IS_CACHED(flags))
-		return remap_pfn_range(vma, vma->vm_start,
+		ret_value = remap_pfn_range(vma, vma->vm_start,
 			       __phys_to_pfn(buffer->priv_phys) + vma->vm_pgoff,
 			       vma->vm_end - vma->vm_start,
 			       vma->vm_page_prot);
 	else
-		return remap_pfn_range(vma, vma->vm_start,
+		ret_value = remap_pfn_range(vma, vma->vm_start,
 			       __phys_to_pfn(buffer->priv_phys) + vma->vm_pgoff,
 					vma->vm_end - vma->vm_start,
 					pgprot_noncached(vma->vm_page_prot));
+
+	if (ret_value)
+		ion_carveout_release_region(carveout_heap);
+	return ret_value;
 }
 
 void ion_carveout_heap_unmap_user(struct ion_heap *heap,
@@ -211,15 +227,7 @@
 {
 	struct ion_carveout_heap *carveout_heap =
 		container_of(heap, struct ion_carveout_heap, heap);
-
-	if (atomic_dec_and_test(&carveout_heap->map_count)) {
-		if (carveout_heap->release_region) {
-			int ret = carveout_heap->release_region(
-						carveout_heap->bus_id);
-			if (ret)
-				pr_err("Unable to release SMI region");
-		}
-	}
+	ion_carveout_release_region(carveout_heap);
 }
 
 int ion_carveout_cache_ops(struct ion_heap *heap, struct ion_buffer *buffer,
@@ -248,20 +256,16 @@
 	return 0;
 }
 
-static unsigned long ion_carveout_get_allocated(struct ion_heap *heap)
+static int ion_carveout_print_debug(struct ion_heap *heap, struct seq_file *s)
 {
 	struct ion_carveout_heap *carveout_heap =
 		container_of(heap, struct ion_carveout_heap, heap);
 
-	return carveout_heap->allocated_bytes;
-}
+	seq_printf(s, "total bytes currently allocated: %lx\n",
+		carveout_heap->allocated_bytes);
+	seq_printf(s, "total heap size: %lx\n", carveout_heap->total_size);
 
-static unsigned long ion_carveout_get_total(struct ion_heap *heap)
-{
-	struct ion_carveout_heap *carveout_heap =
-		container_of(heap, struct ion_carveout_heap, heap);
-
-	return carveout_heap->total_size;
+	return 0;
 }
 
 int ion_carveout_heap_map_iommu(struct ion_buffer *buffer,
@@ -377,8 +381,7 @@
 	.map_dma = ion_carveout_heap_map_dma,
 	.unmap_dma = ion_carveout_heap_unmap_dma,
 	.cache_op = ion_carveout_cache_ops,
-	.get_allocated = ion_carveout_get_allocated,
-	.get_total = ion_carveout_get_total,
+	.print_debug = ion_carveout_print_debug,
 	.map_iommu = ion_carveout_heap_map_iommu,
 	.unmap_iommu = ion_carveout_heap_unmap_iommu,
 };
diff --git a/drivers/gpu/ion/ion_cp_heap.c b/drivers/gpu/ion/ion_cp_heap.c
index 5737d21..16ace6f 100644
--- a/drivers/gpu/ion/ion_cp_heap.c
+++ b/drivers/gpu/ion/ion_cp_heap.c
@@ -25,6 +25,7 @@
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/memory_alloc.h>
+#include <linux/seq_file.h>
 #include <mach/msm_memtypes.h>
 #include <mach/scm.h>
 #include "ion_priv.h"
@@ -39,6 +40,8 @@
  * @base:	the base address of the memory pool.
  * @permission_type:	Identifier for the memory used by SCM for protecting
  *			and unprotecting memory.
+ * @secure_base:	Base address used when securing a heap that is shared.
+ * @secure_size:	Size used when securing a heap that is shared.
  * @lock:	mutex to protect shared access.
  * @heap_secured:	Identifies the heap_id as secure or not.
  * @allocated_bytes:	the total number of allocated bytes from the pool.
@@ -59,6 +62,8 @@
 	struct gen_pool *pool;
 	ion_phys_addr_t base;
 	unsigned int permission_type;
+	ion_phys_addr_t secure_base;
+	size_t secure_size;
 	struct mutex lock;
 	unsigned int heap_secured;
 	unsigned long allocated_bytes;
@@ -94,14 +99,14 @@
 	int ret_value = 0;
 
 	if (cp_heap->heap_secured == NON_SECURED_HEAP) {
-		int ret_value = ion_cp_protect_mem(cp_heap->base,
-				cp_heap->total_size, cp_heap->permission_type);
+		int ret_value = ion_cp_protect_mem(cp_heap->secure_base,
+				cp_heap->secure_size, cp_heap->permission_type);
 		if (ret_value) {
 			pr_err("Failed to protect memory for heap %s - "
-				"error code: %d", heap->name, ret_value);
+				"error code: %d\n", heap->name, ret_value);
 		} else {
 			cp_heap->heap_secured = SECURED_HEAP;
-			pr_debug("Protected heap %s @ 0x%x",
+			pr_debug("Protected heap %s @ 0x%x\n",
 				heap->name, (unsigned int) cp_heap->base);
 		}
 	}
@@ -119,14 +124,14 @@
 
 	if (cp_heap->heap_secured == SECURED_HEAP) {
 		int error_code = ion_cp_unprotect_mem(
-			cp_heap->base, cp_heap->total_size,
+			cp_heap->secure_base, cp_heap->secure_size,
 			cp_heap->permission_type);
 		if (error_code) {
 			pr_err("Failed to un-protect memory for heap %s - "
-				"error code: %d", heap->name, error_code);
+				"error code: %d\n", heap->name, error_code);
 		} else  {
 			cp_heap->heap_secured = NON_SECURED_HEAP;
-			pr_debug("Un-protected heap %s @ 0x%x", heap->name,
+			pr_debug("Un-protected heap %s @ 0x%x\n", heap->name,
 				(unsigned int) cp_heap->base);
 		}
 	}
@@ -148,14 +153,14 @@
 	if (!secure_allocation && cp_heap->heap_secured == SECURED_HEAP) {
 		mutex_unlock(&cp_heap->lock);
 		pr_err("ION cannot allocate un-secure memory from protected"
-			" heap %s", heap->name);
+			" heap %s\n", heap->name);
 		return ION_CP_ALLOCATE_FAIL;
 	}
 
 	if (secure_allocation && cp_heap->umap_count > 0) {
 		mutex_unlock(&cp_heap->lock);
 		pr_err("ION cannot allocate secure memory from heap with "
-			"outstanding user space mappings for heap %s",
+			"outstanding user space mappings for heap %s\n",
 			heap->name);
 		return ION_CP_ALLOCATE_FAIL;
 	}
@@ -178,7 +183,7 @@
 		      cp_heap->allocated_bytes) > size)
 			pr_debug("%s: heap %s has enough memory (%lx) but"
 				" the allocation of size %lx still failed."
-				" Memory is probably fragmented.",
+				" Memory is probably fragmented.\n",
 				__func__, heap->name,
 				cp_heap->total_size -
 				cp_heap->allocated_bytes, size);
@@ -328,7 +333,7 @@
 	mutex_lock(&cp_heap->lock);
 
 	if (cp_heap->heap_secured == SECURED_HEAP && ION_IS_CACHED(flags)) {
-		pr_err("Unable to map secured heap %s as cached", heap->name);
+		pr_err("Unable to map secured heap %s as cached\n", heap->name);
 		mutex_unlock(&cp_heap->lock);
 		return NULL;
 	}
@@ -450,77 +455,34 @@
 	return 0;
 }
 
-static unsigned long ion_cp_get_allocated(struct ion_heap *heap)
+static int ion_cp_print_debug(struct ion_heap *heap, struct seq_file *s)
 {
-	struct ion_cp_heap *cp_heap =
-		container_of(heap, struct ion_cp_heap, heap);
-	unsigned long allocated_bytes;
-
-	mutex_lock(&cp_heap->lock);
-	allocated_bytes = cp_heap->allocated_bytes;
-	mutex_unlock(&cp_heap->lock);
-
-	return allocated_bytes;
-}
-
-static unsigned long ion_cp_get_total(struct ion_heap *heap)
-{
-	struct ion_cp_heap *cp_heap =
-		container_of(heap, struct ion_cp_heap, heap);
-
-	return cp_heap->total_size;
-}
-
-static unsigned long ion_cp_get_umap_count(struct ion_heap *heap)
-{
-	struct ion_cp_heap *cp_heap =
-		container_of(heap, struct ion_cp_heap, heap);
-	unsigned long umap_count;
-
-	mutex_lock(&cp_heap->lock);
-	umap_count = cp_heap->umap_count;
-	mutex_unlock(&cp_heap->lock);
-
-	return umap_count;
-}
-
-static unsigned long ion_cp_get_kmap_count(struct ion_heap *heap)
-{
-	struct ion_cp_heap *cp_heap =
-		container_of(heap, struct ion_cp_heap, heap);
-	unsigned long kmap_count;
-
-	mutex_lock(&cp_heap->lock);
-	kmap_count = cp_heap->kmap_count;
-	mutex_unlock(&cp_heap->lock);
-
-	return kmap_count;
-}
-
-static unsigned long ion_cp_get_alloc_count(struct ion_heap *heap)
-{
-	struct ion_cp_heap *cp_heap =
-		container_of(heap, struct ion_cp_heap, heap);
+	unsigned long total_alloc;
+	unsigned long total_size;
 	unsigned long alloc_count;
-
-	mutex_lock(&cp_heap->lock);
-	alloc_count = cp_heap->alloc_count;
-	mutex_unlock(&cp_heap->lock);
-
-	return alloc_count;
-}
-
-static unsigned long ion_cp_get_secured(struct ion_heap *heap)
-{
+	unsigned long umap_count;
+	unsigned long kmap_count;
+	unsigned long heap_secured;
 	struct ion_cp_heap *cp_heap =
 		container_of(heap, struct ion_cp_heap, heap);
-	unsigned long secured_heap = 0;
 
 	mutex_lock(&cp_heap->lock);
-	secured_heap = cp_heap->heap_secured == SECURED_HEAP;
+	total_alloc = cp_heap->allocated_bytes;
+	total_size = cp_heap->total_size;
+	alloc_count = cp_heap->alloc_count;
+	umap_count = cp_heap->umap_count;
+	kmap_count = cp_heap->kmap_count;
+	heap_secured = cp_heap->heap_secured == SECURED_HEAP;
 	mutex_unlock(&cp_heap->lock);
 
-	return secured_heap;
+	seq_printf(s, "total bytes currently allocated: %lx\n", total_alloc);
+	seq_printf(s, "total heap size: %lx\n", total_size);
+	seq_printf(s, "allocation count: %lx\n", alloc_count);
+	seq_printf(s, "umapping count: %lx\n", umap_count);
+	seq_printf(s, "kmapping count: %lx\n", kmap_count);
+	seq_printf(s, "secured heap: %s\n", heap_secured ? "Yes" : "No");
+
+	return 0;
 }
 
 int ion_cp_secure_heap(struct ion_heap *heap)
@@ -557,32 +519,11 @@
 	.map_dma = ion_cp_heap_map_dma,
 	.unmap_dma = ion_cp_heap_unmap_dma,
 	.cache_op = ion_cp_cache_ops,
-	.get_allocated = ion_cp_get_allocated,
-	.get_total = ion_cp_get_total,
-	.get_umap_cnt = ion_cp_get_umap_count,
-	.get_kmap_cnt = ion_cp_get_kmap_count,
-	.get_alloc_cnt = ion_cp_get_alloc_count,
-	.get_secured = ion_cp_get_secured,
+	.print_debug = ion_cp_print_debug,
 	.secure_heap = ion_cp_secure_heap,
 	.unsecure_heap = ion_cp_unsecure_heap,
 };
 
-static unsigned long ion_cp_get_base(unsigned long size, int memory_type)
-{
-	switch (memory_type) {
-	case ION_EBI_TYPE:
-		return allocate_contiguous_ebi_nomap(size, PAGE_SIZE);
-		break;
-	case ION_SMI_TYPE:
-		return allocate_contiguous_memory_nomap(size, MEMTYPE_SMI,
-							PAGE_SIZE);
-		break;
-	default:
-		return 0;
-	}
-}
-
-
 struct ion_heap *ion_cp_heap_create(struct ion_platform_heap *heap_data)
 {
 	struct ion_cp_heap *cp_heap;
@@ -592,15 +533,6 @@
 	if (!cp_heap)
 		return ERR_PTR(-ENOMEM);
 
-	heap_data->base = ion_cp_get_base(heap_data->size,
-					heap_data->memory_type);
-	if (!heap_data->base) {
-		pr_err("%s: could not get memory for heap %s"
-			" (id %x)\n", __func__, heap_data->name,
-			heap_data->id);
-		goto free_heap;
-	}
-
 	mutex_init(&cp_heap->lock);
 
 	cp_heap->pool = gen_pool_create(12, -1);
@@ -620,10 +552,16 @@
 	cp_heap->heap.ops = &cp_heap_ops;
 	cp_heap->heap.type = ION_HEAP_TYPE_CP;
 	cp_heap->heap_secured = NON_SECURED_HEAP;
+	cp_heap->secure_base = cp_heap->base;
+	cp_heap->secure_size = heap_data->size;
 	if (heap_data->extra_data) {
 		struct ion_cp_heap_pdata *extra_data =
 				heap_data->extra_data;
 		cp_heap->permission_type = extra_data->permission_type;
+		if (extra_data->secure_size) {
+			cp_heap->secure_base = extra_data->secure_base;
+			cp_heap->secure_size = extra_data->secure_size;
+		}
 		if (extra_data->setup_region)
 			cp_heap->bus_id = extra_data->setup_region();
 		if (extra_data->request_region)
@@ -664,7 +602,7 @@
 	unsigned int end;
 	unsigned int permission_type;
 	unsigned char lock;
-};
+} __attribute__ ((__packed__));
 
 
 static int ion_cp_protect_mem(unsigned int phy_base, unsigned int size,
diff --git a/drivers/gpu/ion/ion_priv.h b/drivers/gpu/ion/ion_priv.h
index 98709b6..78dfe6e 100644
--- a/drivers/gpu/ion/ion_priv.h
+++ b/drivers/gpu/ion/ion_priv.h
@@ -139,8 +139,6 @@
 	int (*cache_op)(struct ion_heap *heap, struct ion_buffer *buffer,
 			void *vaddr, unsigned int offset,
 			unsigned int length, unsigned int cmd);
-	unsigned long (*get_allocated)(struct ion_heap *heap);
-	unsigned long (*get_total)(struct ion_heap *heap);
 	int (*map_iommu)(struct ion_buffer *buffer,
 				struct ion_iommu_map *map_data,
 				unsigned int domain_num,
@@ -149,10 +147,7 @@
 				unsigned long iova_length,
 				unsigned long flags);
 	void (*unmap_iommu)(struct ion_iommu_map *data);
-	unsigned long (*get_umap_cnt)(struct ion_heap *heap);
-	unsigned long (*get_kmap_cnt)(struct ion_heap *heap);
-	unsigned long (*get_alloc_cnt)(struct ion_heap *heap);
-	unsigned long (*get_secured)(struct ion_heap *heap);
+	int (*print_debug)(struct ion_heap *heap, struct seq_file *s);
 	int (*secure_heap)(struct ion_heap *heap);
 	int (*unsecure_heap)(struct ion_heap *heap);
 };
diff --git a/drivers/gpu/ion/ion_system_heap.c b/drivers/gpu/ion/ion_system_heap.c
index 5957658..316740e 100644
--- a/drivers/gpu/ion/ion_system_heap.c
+++ b/drivers/gpu/ion/ion_system_heap.c
@@ -2,7 +2,7 @@
  * drivers/gpu/ion/ion_system_heap.c
  *
  * Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-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
@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
 #include <linux/iommu.h>
+#include <linux/seq_file.h>
 #include <mach/iommu_domains.h>
 #include "ion_priv.h"
 #include <mach/memory.h>
@@ -189,9 +190,12 @@
 	return 0;
 }
 
-static unsigned long ion_system_heap_get_allocated(struct ion_heap *heap)
+static int ion_system_print_debug(struct ion_heap *heap, struct seq_file *s)
 {
-	return atomic_read(&system_heap_allocated);
+	seq_printf(s, "total bytes currently allocated: %lx\n",
+			(unsigned long) atomic_read(&system_heap_allocated));
+
+	return 0;
 }
 
 int ion_system_heap_map_iommu(struct ion_buffer *buffer,
@@ -274,7 +278,7 @@
 	.unmap_kernel = ion_system_heap_unmap_kernel,
 	.map_user = ion_system_heap_map_user,
 	.cache_op = ion_system_heap_cache_ops,
-	.get_allocated = ion_system_heap_get_allocated,
+	.print_debug = ion_system_print_debug,
 	.map_iommu = ion_system_heap_map_iommu,
 	.unmap_iommu = ion_system_heap_unmap_iommu,
 };
@@ -387,9 +391,13 @@
 	return 0;
 }
 
-static unsigned long ion_system_contig_heap_get_allocated(struct ion_heap *heap)
+static int ion_system_contig_print_debug(struct ion_heap *heap,
+					 struct seq_file *s)
 {
-	return atomic_read(&system_contig_heap_allocated);
+	seq_printf(s, "total bytes currently allocated: %lx\n",
+		(unsigned long) atomic_read(&system_contig_heap_allocated));
+
+	return 0;
 }
 
 int ion_system_contig_heap_map_iommu(struct ion_buffer *buffer,
@@ -470,7 +478,7 @@
 	.unmap_kernel = ion_system_heap_unmap_kernel,
 	.map_user = ion_system_contig_heap_map_user,
 	.cache_op = ion_system_contig_heap_cache_ops,
-	.get_allocated = ion_system_contig_heap_get_allocated,
+	.print_debug = ion_system_contig_print_debug,
 	.map_iommu = ion_system_contig_heap_map_iommu,
 	.unmap_iommu = ion_system_heap_unmap_iommu,
 };
diff --git a/drivers/gpu/ion/msm/msm_ion.c b/drivers/gpu/ion/msm/msm_ion.c
index 3df2b53..f71f514 100644
--- a/drivers/gpu/ion/msm/msm_ion.c
+++ b/drivers/gpu/ion/msm/msm_ion.c
@@ -42,21 +42,119 @@
 }
 EXPORT_SYMBOL(msm_ion_unsecure_heap);
 
-static unsigned long msm_ion_get_base(unsigned long size, int memory_type)
+static unsigned long msm_ion_get_base(unsigned long size, int memory_type,
+				    unsigned int align)
 {
 	switch (memory_type) {
 	case ION_EBI_TYPE:
-		return allocate_contiguous_ebi_nomap(size, PAGE_SIZE);
+		return allocate_contiguous_ebi_nomap(size, align);
 		break;
 	case ION_SMI_TYPE:
 		return allocate_contiguous_memory_nomap(size, MEMTYPE_SMI,
-							PAGE_SIZE);
+							align);
 		break;
 	default:
+		pr_err("%s: Unknown memory type %d\n", __func__, memory_type);
 		return 0;
 	}
 }
 
+static struct ion_platform_heap *find_heap(const struct ion_platform_heap
+					   heap_data[],
+					   unsigned int nr_heaps,
+					   int heap_id)
+{
+	unsigned int i;
+	for (i = 0; i < nr_heaps; ++i) {
+		const struct ion_platform_heap *heap = &heap_data[i];
+		if (heap->id == heap_id)
+			return (struct ion_platform_heap *) heap;
+	}
+	return 0;
+}
+
+static void allocate_co_memory(struct ion_platform_heap *heap,
+			       struct ion_platform_heap heap_data[],
+			       unsigned int nr_heaps)
+{
+	struct ion_co_heap_pdata *co_heap_data =
+		(struct ion_co_heap_pdata *) heap->extra_data;
+	if (co_heap_data->adjacent_mem_id != INVALID_HEAP_ID) {
+		struct ion_platform_heap *shared_heap =
+			find_heap(heap_data, nr_heaps,
+				  co_heap_data->adjacent_mem_id);
+		if (shared_heap) {
+			struct ion_cp_heap_pdata *cp_data =
+			   (struct ion_cp_heap_pdata *) shared_heap->extra_data;
+			heap->base = msm_ion_get_base(
+				heap->size + shared_heap->size,
+				shared_heap->memory_type,
+				co_heap_data->align);
+			if (heap->base) {
+				shared_heap->base = heap->base + heap->size;
+				cp_data->secure_base = heap->base;
+				cp_data->secure_size =
+						heap->size + shared_heap->size;
+			} else {
+				pr_err("%s: could not get memory for heap %s "
+				   "(id %x)\n", __func__, heap->name, heap->id);
+			}
+
+		}
+	}
+}
+
+/* Fixup heaps in board file to support two heaps being adjacent to each other.
+ * A flag (adjacent_mem_id) in the platform data tells us that the heap phy
+ * memory location must be adjacent to the specified heap. We do this by
+ * carving out memory for both heaps and then splitting up the memory to the
+ * two heaps. The heap specifying the "adjacent_mem_id" get the base of the
+ * memory while heap specified in "adjacent_mem_id" get base+size as its
+ * base address.
+ * Note: Modifies platform data and allocates memory.
+ */
+static void msm_ion_heap_fixup(struct ion_platform_heap heap_data[],
+			       unsigned int nr_heaps)
+{
+	unsigned int i;
+
+	for (i = 0; i < nr_heaps; i++) {
+		struct ion_platform_heap *heap = &heap_data[i];
+		if (!heap->base && heap->type == ION_HEAP_TYPE_CARVEOUT) {
+			if (heap->extra_data)
+				allocate_co_memory(heap, heap_data, nr_heaps);
+		}
+	}
+}
+
+static void msm_ion_allocate(struct ion_platform_heap *heap)
+{
+
+	if (!heap->base && heap->extra_data) {
+		unsigned int align = 0;
+		switch (heap->type) {
+		case ION_HEAP_TYPE_CARVEOUT:
+			align =
+			((struct ion_co_heap_pdata *) heap->extra_data)->align;
+			break;
+		case ION_HEAP_TYPE_CP:
+			align =
+			((struct ion_cp_heap_pdata *) heap->extra_data)->align;
+			break;
+		default:
+			break;
+		}
+		if (align) {
+			heap->base = msm_ion_get_base(heap->size,
+						      heap->memory_type,
+						      align);
+			if (!heap->base)
+				pr_err("%s: could not get memory for heap %s "
+				   "(id %x)\n", __func__, heap->name, heap->id);
+		}
+	}
+}
+
 static int msm_ion_probe(struct platform_device *pdev)
 {
 	struct ion_platform_data *pdata = pdev->dev.platform_data;
@@ -78,28 +176,26 @@
 		goto freeheaps;
 	}
 
+	msm_ion_heap_fixup(pdata->heaps, num_heaps);
+
 	/* create the heaps as specified in the board file */
 	for (i = 0; i < num_heaps; i++) {
 		struct ion_platform_heap *heap_data = &pdata->heaps[i];
-
-		if (heap_data->type == ION_HEAP_TYPE_CARVEOUT) {
-			heap_data->base = msm_ion_get_base(heap_data->size,
-							heap_data->memory_type);
-			if (!heap_data->base) {
-				pr_err("%s: could not get memory for heap %s"
-					" (id %x)\n", __func__, heap_data->name,
-					heap_data->id);
-				continue;
-			}
-		}
+		msm_ion_allocate(heap_data);
 
 		heaps[i] = ion_heap_create(heap_data);
 		if (IS_ERR_OR_NULL(heaps[i])) {
-			pr_err("%s: could not create ion heap %s"
-				" (id %x)\n", __func__, heap_data->name,
-				heap_data->id);
 			heaps[i] = 0;
 			continue;
+		} else {
+			if (heap_data->size)
+				pr_info("ION heap %s created at %lx "
+					"with size %x\n", heap_data->name,
+							  heap_data->base,
+							  heap_data->size);
+			else
+				pr_info("ION heap %s created\n",
+							  heap_data->name);
 		}
 
 		ion_device_add_heap(idev, heaps[i]);
diff --git a/drivers/gpu/msm/Makefile b/drivers/gpu/msm/Makefile
index 39a7b04..908b63d 100644
--- a/drivers/gpu/msm/Makefile
+++ b/drivers/gpu/msm/Makefile
@@ -14,7 +14,7 @@
 msm_kgsl_core-$(CONFIG_MSM_KGSL_CFF_DUMP) += kgsl_cffdump.o
 msm_kgsl_core-$(CONFIG_MSM_KGSL_DRM) += kgsl_drm.o
 msm_kgsl_core-$(CONFIG_MSM_SCM) += kgsl_pwrscale_trustzone.o
-msm_kgsl_core-$(CONFIG_MSM_SLEEP_STATS) += kgsl_pwrscale_idlestats.o
+msm_kgsl_core-$(CONFIG_MSM_SLEEP_STATS_DEVICE) += kgsl_pwrscale_idlestats.o
 
 msm_adreno-y += \
 	adreno_ringbuffer.o \
diff --git a/drivers/gpu/msm/kgsl_pwrscale.c b/drivers/gpu/msm/kgsl_pwrscale.c
index 55e5383..4c9a239 100644
--- a/drivers/gpu/msm/kgsl_pwrscale.c
+++ b/drivers/gpu/msm/kgsl_pwrscale.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
@@ -42,7 +42,7 @@
 #ifdef CONFIG_MSM_SCM
 	&kgsl_pwrscale_policy_tz,
 #endif
-#ifdef CONFIG_MSM_SLEEP_STATS
+#ifdef CONFIG_MSM_SLEEP_STATS_DEVICE
 	&kgsl_pwrscale_policy_idlestats,
 #endif
 	NULL
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 3c98a75..2453b6b 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -306,6 +306,12 @@
 	u8 t7_data[T7_DATA_SIZE];
 	u16 t7_start_addr;
 	u8 t9_ctrl;
+	u32 keyarray_old;
+	u32 keyarray_new;
+	u8 t9_max_reportid;
+	u8 t9_min_reportid;
+	u8 t15_max_reportid;
+	u8 t15_min_reportid;
 };
 
 static bool mxt_object_readable(unsigned int type)
@@ -670,16 +676,48 @@
 	mxt_input_report(data, id);
 }
 
+static void mxt_handle_key_array(struct mxt_data *data,
+				struct mxt_message *message)
+{
+	u32 keys_changed;
+	int i;
+
+	if (!data->pdata->key_codes) {
+		dev_err(&data->client->dev, "keyarray is not supported\n");
+		return;
+	}
+
+	data->keyarray_new = message->message[1] |
+				(message->message[2] << 8) |
+				(message->message[3] << 16) |
+				(message->message[4] << 24);
+
+	keys_changed = data->keyarray_old ^ data->keyarray_new;
+
+	if (!keys_changed) {
+		dev_dbg(&data->client->dev, "no keys changed\n");
+		return;
+	}
+
+	for (i = 0; i < MXT_KEYARRAY_MAX_KEYS; i++) {
+		if (!(keys_changed & (1 << i)))
+			continue;
+
+		input_report_key(data->input_dev, data->pdata->key_codes[i],
+					(data->keyarray_new & (1 << i)));
+		input_sync(data->input_dev);
+	}
+
+	data->keyarray_old = data->keyarray_new;
+}
+
 static irqreturn_t mxt_interrupt(int irq, void *dev_id)
 {
 	struct mxt_data *data = dev_id;
 	struct mxt_message message;
-	struct mxt_object *object;
 	struct device *dev = &data->client->dev;
 	int id;
 	u8 reportid;
-	u8 max_reportid;
-	u8 min_reportid;
 
 	do {
 		if (mxt_read_message(data, &message)) {
@@ -688,16 +726,20 @@
 		}
 		reportid = message.reportid;
 
-		/* whether reportid is thing of MXT_TOUCH_MULTI_T9 */
-		object = mxt_get_object(data, MXT_TOUCH_MULTI_T9);
-		if (!object)
-			goto end;
-		max_reportid = object->max_reportid;
-		min_reportid = max_reportid - object->num_report_ids + 1;
-		id = reportid - min_reportid;
+		if (!reportid) {
+			dev_dbg(dev, "Report id 0 is reserved\n");
+			continue;
+		}
 
-		if (reportid >= min_reportid && reportid <= max_reportid)
+		/* check whether report id is part of T9 or T15 */
+		id = reportid - data->t9_min_reportid;
+
+		if (reportid >= data->t9_min_reportid &&
+					reportid <= data->t9_max_reportid)
 			mxt_input_touchevent(data, &message, id);
+		else if (reportid >= data->t15_min_reportid &&
+					reportid <= data->t15_max_reportid)
+			mxt_handle_key_array(data, &message);
 		else
 			mxt_dump_message(dev, &message);
 	} while (reportid != 0xff);
@@ -857,6 +899,8 @@
 	u8 val;
 	u8 command_register;
 	struct mxt_object *t7_object;
+	struct mxt_object *t9_object;
+	struct mxt_object *t15_object;
 
 	error = mxt_get_info(data);
 	if (error)
@@ -903,6 +947,28 @@
 		goto free_object_table;
 	}
 
+	/* Store T9, T15's min and max report ids */
+	t9_object = mxt_get_object(data, MXT_TOUCH_MULTI_T9);
+	if (!t9_object) {
+		dev_err(&client->dev, "Failed to get T9 object\n");
+		error = -EINVAL;
+		goto free_object_table;
+	}
+	data->t9_max_reportid = t9_object->max_reportid;
+	data->t9_min_reportid = t9_object->max_reportid -
+					t9_object->num_report_ids + 1;
+
+	if (data->pdata->key_codes) {
+		t15_object = mxt_get_object(data, MXT_TOUCH_KEYARRAY_T15);
+		if (!t15_object)
+			dev_dbg(&client->dev, "T15 object is not available\n");
+		else {
+			data->t15_max_reportid = t15_object->max_reportid;
+			data->t15_min_reportid = t15_object->max_reportid -
+						t15_object->num_report_ids + 1;
+		}
+	}
+
 	/* Backup to memory */
 	mxt_write_object(data, MXT_GEN_COMMAND_T6,
 			MXT_COMMAND_BACKUPNV,
@@ -1562,7 +1628,7 @@
 	const struct mxt_platform_data *pdata = client->dev.platform_data;
 	struct mxt_data *data;
 	struct input_dev *input_dev;
-	int error;
+	int error, i;
 
 	if (!pdata)
 		return -EINVAL;
@@ -1608,6 +1674,15 @@
 	input_set_abs_params(input_dev, ABS_MT_PRESSURE,
 			     0, 255, 0, 0);
 
+	/* set key array supported keys */
+	if (pdata->key_codes) {
+		for (i = 0; i < MXT_KEYARRAY_MAX_KEYS; i++) {
+			if (pdata->key_codes[i])
+				input_set_capability(input_dev, EV_KEY,
+							pdata->key_codes[i]);
+		}
+	}
+
 	input_set_drvdata(input_dev, data);
 	i2c_set_clientdata(client, data);
 
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index 835f8c4..5ed2ad7 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -2086,7 +2086,8 @@
 	struct sk_buff *skb)
 {
 	struct iris_device *radio = video_get_drvdata(video_get_dev());
-	if (radio->fm_st_rsp.station_rsp.serv_avble)
+	u8 serv_avble = skb->data[0];
+	if (serv_avble)
 		iris_q_event(radio, IRIS_EVT_ABOVE_TH);
 	else
 		iris_q_event(radio, IRIS_EVT_BELOW_TH);
diff --git a/drivers/mfd/pm8038-core.c b/drivers/mfd/pm8038-core.c
index c90ea16..8a9d289 100644
--- a/drivers/mfd/pm8038-core.c
+++ b/drivers/mfd/pm8038-core.c
@@ -1,5 +1,5 @@
 /*
- * 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
@@ -21,6 +21,7 @@
 #include <linux/msm_ssbi.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/pm8xxx/pm8038.h>
+#include <linux/mfd/pm8xxx/pm8921.h>
 #include <linux/mfd/pm8xxx/core.h>
 #include <linux/mfd/pm8xxx/regulator.h>
 
@@ -155,6 +156,63 @@
 	.num_resources	= ARRAY_SIZE(adc_cell_resources),
 };
 
+static const struct resource charger_cell_resources[] __devinitconst = {
+	SINGLE_IRQ_RESOURCE("USBIN_VALID_IRQ", PM8921_USBIN_VALID_IRQ),
+	SINGLE_IRQ_RESOURCE("USBIN_OV_IRQ", PM8921_USBIN_OV_IRQ),
+	SINGLE_IRQ_RESOURCE("BATT_INSERTED_IRQ", PM8921_BATT_INSERTED_IRQ),
+	SINGLE_IRQ_RESOURCE("VBATDET_LOW_IRQ", PM8921_VBATDET_LOW_IRQ),
+	SINGLE_IRQ_RESOURCE("USBIN_UV_IRQ", PM8921_USBIN_UV_IRQ),
+	SINGLE_IRQ_RESOURCE("VBAT_OV_IRQ", PM8921_VBAT_OV_IRQ),
+	SINGLE_IRQ_RESOURCE("CHGWDOG_IRQ", PM8921_CHGWDOG_IRQ),
+	SINGLE_IRQ_RESOURCE("VCP_IRQ", PM8921_VCP_IRQ),
+	SINGLE_IRQ_RESOURCE("ATCDONE_IRQ", PM8921_ATCDONE_IRQ),
+	SINGLE_IRQ_RESOURCE("ATCFAIL_IRQ", PM8921_ATCFAIL_IRQ),
+	SINGLE_IRQ_RESOURCE("CHGDONE_IRQ", PM8921_CHGDONE_IRQ),
+	SINGLE_IRQ_RESOURCE("CHGFAIL_IRQ", PM8921_CHGFAIL_IRQ),
+	SINGLE_IRQ_RESOURCE("CHGSTATE_IRQ", PM8921_CHGSTATE_IRQ),
+	SINGLE_IRQ_RESOURCE("LOOP_CHANGE_IRQ", PM8921_LOOP_CHANGE_IRQ),
+	SINGLE_IRQ_RESOURCE("FASTCHG_IRQ", PM8921_FASTCHG_IRQ),
+	SINGLE_IRQ_RESOURCE("TRKLCHG_IRQ", PM8921_TRKLCHG_IRQ),
+	SINGLE_IRQ_RESOURCE("BATT_REMOVED_IRQ", PM8921_BATT_REMOVED_IRQ),
+	SINGLE_IRQ_RESOURCE("BATTTEMP_HOT_IRQ", PM8921_BATTTEMP_HOT_IRQ),
+	SINGLE_IRQ_RESOURCE("CHGHOT_IRQ", PM8921_CHGHOT_IRQ),
+	SINGLE_IRQ_RESOURCE("BATTTEMP_COLD_IRQ", PM8921_BATTTEMP_COLD_IRQ),
+	SINGLE_IRQ_RESOURCE("CHG_GONE_IRQ", PM8921_CHG_GONE_IRQ),
+	SINGLE_IRQ_RESOURCE("BAT_TEMP_OK_IRQ", PM8921_BAT_TEMP_OK_IRQ),
+	SINGLE_IRQ_RESOURCE("COARSE_DET_LOW_IRQ", PM8921_COARSE_DET_LOW_IRQ),
+	SINGLE_IRQ_RESOURCE("VDD_LOOP_IRQ", PM8921_VDD_LOOP_IRQ),
+	SINGLE_IRQ_RESOURCE("VREG_OV_IRQ", PM8921_VREG_OV_IRQ),
+	SINGLE_IRQ_RESOURCE("VBATDET_IRQ", PM8921_VBATDET_IRQ),
+	SINGLE_IRQ_RESOURCE("BATFET_IRQ", PM8921_BATFET_IRQ),
+	SINGLE_IRQ_RESOURCE("PSI_IRQ", PM8921_PSI_IRQ),
+	SINGLE_IRQ_RESOURCE("DCIN_VALID_IRQ", PM8921_DCIN_VALID_IRQ),
+	SINGLE_IRQ_RESOURCE("DCIN_OV_IRQ", PM8921_DCIN_OV_IRQ),
+	SINGLE_IRQ_RESOURCE("DCIN_UV_IRQ", PM8921_DCIN_UV_IRQ),
+};
+
+static const struct resource bms_cell_resources[] __devinitconst = {
+	SINGLE_IRQ_RESOURCE("PM8921_BMS_SBI_WRITE_OK", PM8921_BMS_SBI_WRITE_OK),
+	SINGLE_IRQ_RESOURCE("PM8921_BMS_CC_THR", PM8921_BMS_CC_THR),
+	SINGLE_IRQ_RESOURCE("PM8921_BMS_VSENSE_THR", PM8921_BMS_VSENSE_THR),
+	SINGLE_IRQ_RESOURCE("PM8921_BMS_VSENSE_FOR_R", PM8921_BMS_VSENSE_FOR_R),
+	SINGLE_IRQ_RESOURCE("PM8921_BMS_OCV_FOR_R", PM8921_BMS_OCV_FOR_R),
+	SINGLE_IRQ_RESOURCE("PM8921_BMS_GOOD_OCV", PM8921_BMS_GOOD_OCV),
+	SINGLE_IRQ_RESOURCE("PM8921_BMS_VSENSE_AVG", PM8921_BMS_VSENSE_AVG),
+};
+
+static struct mfd_cell charger_cell __devinitdata = {
+	.name		= PM8921_CHARGER_DEV_NAME,
+	.id		= -1,
+	.resources	= charger_cell_resources,
+	.num_resources	= ARRAY_SIZE(charger_cell_resources),
+};
+
+static struct mfd_cell bms_cell __devinitdata = {
+	.name		= PM8921_BMS_DEV_NAME,
+	.id		= -1,
+	.resources	= bms_cell_resources,
+	.num_resources	= ARRAY_SIZE(bms_cell_resources),
+};
 static const struct resource mpp_cell_resources[] __devinitconst = {
 	{
 		.start	= PM8038_IRQ_BLOCK_BIT(PM8038_MPP_BLOCK_START, 0),
@@ -470,6 +528,39 @@
 		}
 	}
 
+	if (pdata->charger_pdata) {
+		pdata->charger_pdata->charger_cdata.vbat_channel = CHANNEL_VBAT;
+		pdata->charger_pdata->charger_cdata.batt_temp_channel
+						= CHANNEL_BATT_THERM;
+		pdata->charger_pdata->charger_cdata.batt_id_channel
+						= CHANNEL_BATT_ID;
+		charger_cell.platform_data = pdata->charger_pdata;
+		charger_cell.pdata_size =
+				sizeof(struct pm8921_charger_platform_data);
+		ret = mfd_add_devices(pmic->dev, 0, &charger_cell, 1, NULL,
+					irq_base);
+		if (ret) {
+			pr_err("Failed to add charger subdevice ret=%d\n", ret);
+			goto bail;
+		}
+	}
+
+	if (pdata->bms_pdata) {
+		pdata->bms_pdata->bms_cdata.batt_temp_channel
+						= CHANNEL_BATT_THERM;
+		pdata->bms_pdata->bms_cdata.vbat_channel = CHANNEL_VBAT;
+		pdata->bms_pdata->bms_cdata.ref625mv_channel = CHANNEL_625MV;
+		pdata->bms_pdata->bms_cdata.ref1p25v_channel = CHANNEL_125V;
+		pdata->bms_pdata->bms_cdata.batt_id_channel = CHANNEL_BATT_ID;
+		bms_cell.platform_data = pdata->bms_pdata;
+		bms_cell.pdata_size = sizeof(struct pm8921_bms_platform_data);
+		ret = mfd_add_devices(pmic->dev, 0, &bms_cell, 1, NULL,
+					irq_base);
+		if (ret) {
+			pr_err("Failed to add bms subdevice ret=%d\n", ret);
+			goto bail;
+		}
+	}
 	return 0;
 bail:
 	if (pmic->irq_chip) {
diff --git a/drivers/mfd/timpani-codec.c b/drivers/mfd/timpani-codec.c
index d2c2eb4..4b9aef2 100644
--- a/drivers/mfd/timpani-codec.c
+++ b/drivers/mfd/timpani-codec.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
@@ -2819,7 +2819,7 @@
 	u8 reg_mask = 0;
 	int rc = 0;
 
-	for (i = 0; i < 0xEF; i++) {
+	for (i = 0; i < ARRAY_SIZE(timpani_regset); i++) {
 		if (timpani_regset[i].reg_addr == reg) {
 			for (j = 0; j < TIMPANI_MAX_FIELDS; j++) {
 				fld_mask = timpani_regset[i].fld_ref_cnt[j].mask
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index dce8d6d..c3a756d 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -234,7 +234,6 @@
 	if (!skb->protocol)
 		skb->protocol = eth_type_trans(skb, dev->net);
 
-	skb->protocol = eth_type_trans (skb, dev->net);
 	dev->net->stats.rx_packets++;
 	dev->net->stats.rx_bytes += skb->len;
 
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index 9f689f1..19c0115 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -19,10 +19,12 @@
  */
 
 #include <linux/errno.h>
+#include <linux/list.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_irq.h>
 #include <linux/string.h>
+#include <linux/slab.h>
 
 /* For archs that don't support NO_IRQ (such as x86), provide a dummy value */
 #ifndef NO_IRQ
@@ -386,3 +388,110 @@
 
 	return i;
 }
+
+struct intc_desc {
+	struct list_head	list;
+	struct device_node	*dev;
+	struct device_node	*interrupt_parent;
+};
+
+/**
+ * of_irq_init - Scan and init matching interrupt controllers in DT
+ * @matches: 0 terminated array of nodes to match and init function to call
+ *
+ * This function scans the device tree for matching interrupt controller nodes,
+ * and calls their initialization functions in order with parents first.
+ */
+void __init of_irq_init(const struct of_device_id *matches)
+{
+	struct device_node *np, *parent = NULL;
+	struct intc_desc *desc, *temp_desc;
+	struct list_head intc_desc_list, intc_parent_list;
+
+	INIT_LIST_HEAD(&intc_desc_list);
+	INIT_LIST_HEAD(&intc_parent_list);
+
+	for_each_matching_node(np, matches) {
+		if (!of_find_property(np, "interrupt-controller", NULL))
+			continue;
+		/*
+		 * Here, we allocate and populate an intc_desc with the node
+		 * pointer, interrupt-parent device_node etc.
+		 */
+		desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+		if (WARN_ON(!desc))
+			goto err;
+
+		desc->dev = np;
+		desc->interrupt_parent = of_irq_find_parent(np);
+		if (desc->interrupt_parent == np)
+			desc->interrupt_parent = NULL;
+		list_add_tail(&desc->list, &intc_desc_list);
+	}
+
+	/*
+	 * The root irq controller is the one without an interrupt-parent.
+	 * That one goes first, followed by the controllers that reference it,
+	 * followed by the ones that reference the 2nd level controllers, etc.
+	 */
+	while (!list_empty(&intc_desc_list)) {
+		/*
+		 * Process all controllers with the current 'parent'.
+		 * First pass will be looking for NULL as the parent.
+		 * The assumption is that NULL parent means a root controller.
+		 */
+		list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
+			const struct of_device_id *match;
+			int ret;
+			of_irq_init_cb_t irq_init_cb;
+
+			if (desc->interrupt_parent != parent)
+				continue;
+
+			list_del(&desc->list);
+			match = of_match_node(matches, desc->dev);
+			if (WARN(!match->data,
+			    "of_irq_init: no init function for %s\n",
+			    match->compatible)) {
+				kfree(desc);
+				continue;
+			}
+
+			pr_debug("of_irq_init: init %s @ %p, parent %p\n",
+				 match->compatible,
+				 desc->dev, desc->interrupt_parent);
+			irq_init_cb = match->data;
+			ret = irq_init_cb(desc->dev, desc->interrupt_parent);
+			if (ret) {
+				kfree(desc);
+				continue;
+			}
+
+			/*
+			 * This one is now set up; add it to the parent list so
+			 * its children can get processed in a subsequent pass.
+			 */
+			list_add_tail(&desc->list, &intc_parent_list);
+		}
+
+		/* Get the next pending parent that might have children */
+		desc = list_first_entry(&intc_parent_list, typeof(*desc), list);
+		if (list_empty(&intc_parent_list) || !desc) {
+			pr_err("of_irq_init: children remain, but no parents\n");
+			break;
+		}
+		list_del(&desc->list);
+		parent = desc->dev;
+		kfree(desc);
+	}
+
+	list_for_each_entry_safe(desc, temp_desc, &intc_parent_list, list) {
+		list_del(&desc->list);
+		kfree(desc);
+	}
+err:
+	list_for_each_entry_safe(desc, temp_desc, &intc_desc_list, list) {
+		list_del(&desc->list);
+		kfree(desc);
+	}
+}
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 5b2328d..2b58215 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1319,6 +1319,40 @@
 }
 EXPORT_SYMBOL_GPL(regulator_get);
 
+static void devm_regulator_release(struct device *dev, void *res)
+{
+	regulator_put(*(struct regulator **)res);
+}
+
+/**
+ * devm_regulator_get - Resource managed regulator_get()
+ * @dev: device for regulator "consumer"
+ * @id: Supply name or regulator ID.
+ *
+ * Managed regulator_get(). Regulators returned from this function are
+ * automatically regulator_put() on driver detach. See regulator_get() for more
+ * information.
+ */
+struct regulator *devm_regulator_get(struct device *dev, const char *id)
+{
+	struct regulator **ptr, *regulator;
+
+	ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL);
+	if (!ptr)
+		return ERR_PTR(-ENOMEM);
+
+	regulator = regulator_get(dev, id);
+	if (!IS_ERR(regulator)) {
+		*ptr = regulator;
+		devres_add(dev, ptr);
+	} else {
+		devres_free(ptr);
+	}
+
+	return regulator;
+}
+EXPORT_SYMBOL_GPL(devm_regulator_get);
+
 /**
  * regulator_get_exclusive - obtain exclusive access to a regulator.
  * @dev: device for regulator "consumer"
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index e13b4c4..a0763da 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -3,6 +3,7 @@
  * Android IPC Subsystem
  *
  * Copyright (C) 2007-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
@@ -97,9 +98,9 @@
 	BINDER_DEBUG_BUFFER_ALLOC           = 1U << 13,
 	BINDER_DEBUG_PRIORITY_CAP           = 1U << 14,
 	BINDER_DEBUG_BUFFER_ALLOC_ASYNC     = 1U << 15,
+	BINDER_DEBUG_TOP_ERRORS             = 1U << 16,
 };
-static uint32_t binder_debug_mask = BINDER_DEBUG_USER_ERROR |
-	BINDER_DEBUG_FAILED_TRANSACTION | BINDER_DEBUG_DEAD_TRANSACTION;
+static uint32_t binder_debug_mask;
 module_param_named(debug_mask, binder_debug_mask, uint, S_IWUSR | S_IRUGO);
 
 static int binder_debug_no_lock;
@@ -638,7 +639,8 @@
 		goto free_range;
 
 	if (vma == NULL) {
-		printk(KERN_ERR "binder: %d: binder_alloc_buf failed to "
+		binder_debug(BINDER_DEBUG_TOP_ERRORS,
+		       "binder: %d: binder_alloc_buf failed to "
 		       "map pages in userspace, no vma\n", proc->pid);
 		goto err_no_vma;
 	}
@@ -651,7 +653,8 @@
 		BUG_ON(*page);
 		*page = alloc_page(GFP_KERNEL | __GFP_ZERO);
 		if (*page == NULL) {
-			printk(KERN_ERR "binder: %d: binder_alloc_buf failed "
+			binder_debug(BINDER_DEBUG_TOP_ERRORS,
+			       "binder: %d: binder_alloc_buf failed "
 			       "for page at %p\n", proc->pid, page_addr);
 			goto err_alloc_page_failed;
 		}
@@ -660,7 +663,8 @@
 		page_array_ptr = page;
 		ret = map_vm_area(&tmp_area, PAGE_KERNEL, &page_array_ptr);
 		if (ret) {
-			printk(KERN_ERR "binder: %d: binder_alloc_buf failed "
+			binder_debug(BINDER_DEBUG_TOP_ERRORS,
+			       "binder: %d: binder_alloc_buf failed "
 			       "to map page at %p in kernel\n",
 			       proc->pid, page_addr);
 			goto err_map_kernel_failed;
@@ -669,7 +673,8 @@
 			(uintptr_t)page_addr + proc->user_buffer_offset;
 		ret = vm_insert_page(vma, user_page_addr, page[0]);
 		if (ret) {
-			printk(KERN_ERR "binder: %d: binder_alloc_buf failed "
+			binder_debug(BINDER_DEBUG_TOP_ERRORS,
+			       "binder: %d: binder_alloc_buf failed "
 			       "to map page at %lx in userspace\n",
 			       proc->pid, user_page_addr);
 			goto err_vm_insert_page_failed;
@@ -718,7 +723,8 @@
 	size_t size;
 
 	if (proc->vma == NULL) {
-		printk(KERN_ERR "binder: %d: binder_alloc_buf, no vma\n",
+		binder_debug(BINDER_DEBUG_TOP_ERRORS,
+		       "binder: %d: binder_alloc_buf, no vma\n",
 		       proc->pid);
 		return NULL;
 	}
@@ -756,7 +762,8 @@
 		}
 	}
 	if (best_fit == NULL) {
-		printk(KERN_ERR "binder: %d: binder_alloc_buf size %zd failed, "
+		binder_debug(BINDER_DEBUG_TOP_ERRORS,
+		       "binder: %d: binder_alloc_buf size %zd failed, "
 		       "no address space\n", proc->pid, size);
 		return NULL;
 	}
@@ -991,7 +998,8 @@
 			    node->internal_strong_refs == 0 &&
 			    !(node == binder_context_mgr_node &&
 			    node->has_strong_ref)) {
-				printk(KERN_ERR "binder: invalid inc strong "
+				binder_debug(BINDER_DEBUG_TOP_ERRORS,
+					"binder: invalid inc strong "
 					"node for %d\n", node->debug_id);
 				return -EINVAL;
 			}
@@ -1007,7 +1015,8 @@
 			node->local_weak_refs++;
 		if (!node->has_weak_ref && list_empty(&node->work.entry)) {
 			if (target_list == NULL) {
-				printk(KERN_ERR "binder: invalid inc weak node "
+				binder_debug(BINDER_DEBUG_TOP_ERRORS,
+					"binder: invalid inc weak node "
 					"for %d\n", node->debug_id);
 				return -EINVAL;
 			}
@@ -1044,7 +1053,7 @@
 			if (node->proc) {
 				rb_erase(&node->rb_node, &node->proc->nodes);
 				binder_debug(BINDER_DEBUG_INTERNAL_REFS,
-					     "binder: refless node %d deleted\n",
+					    "binder: refless node %d deleted\n",
 					     node->debug_id);
 			} else {
 				hlist_del(&node->dead_node);
@@ -1263,14 +1272,16 @@
 				binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
 					     "binder: send failed reply for "
 					     "transaction %d to %d:%d\n",
-					      t->debug_id, target_thread->proc->pid,
+					      t->debug_id,
+					      target_thread->proc->pid,
 					      target_thread->pid);
 
 				binder_pop_transaction(target_thread, t);
 				target_thread->return_error = error_code;
 				wake_up_interruptible(&target_thread->wait);
 			} else {
-				printk(KERN_ERR "binder: reply failed, target "
+				binder_debug(BINDER_DEBUG_TOP_ERRORS,
+					"binder: reply failed, target "
 					"thread, %d:%d, has error code %d "
 					"already\n", target_thread->proc->pid,
 					target_thread->pid,
@@ -1308,14 +1319,15 @@
 	int debug_id = buffer->debug_id;
 
 	binder_debug(BINDER_DEBUG_TRANSACTION,
-		     "binder: %d buffer release %d, size %zd-%zd, failed at %p\n",
-		     proc->pid, buffer->debug_id,
+		     "binder: %d buffer release %d, size %zd-%zd, failed at"
+		     " %p\n", proc->pid, buffer->debug_id,
 		     buffer->data_size, buffer->offsets_size, failed_at);
 
 	if (buffer->target_node)
 		binder_dec_node(buffer->target_node, 1, 0);
 
-	offp = (size_t *)(buffer->data + ALIGN(buffer->data_size, sizeof(void *)));
+	offp = (size_t *)(buffer->data + ALIGN(buffer->data_size,
+				sizeof(void *)));
 	if (failed_at)
 		off_end = failed_at;
 	else
@@ -1325,7 +1337,8 @@
 		if (*offp > buffer->data_size - sizeof(*fp) ||
 		    buffer->data_size < sizeof(*fp) ||
 		    !IS_ALIGNED(*offp, sizeof(void *))) {
-			printk(KERN_ERR "binder: transaction release %d bad"
+			binder_debug(BINDER_DEBUG_TOP_ERRORS,
+					"binder: transaction release %d bad"
 					"offset %zd, size %zd\n", debug_id,
 					*offp, buffer->data_size);
 			continue;
@@ -1334,29 +1347,35 @@
 		switch (fp->type) {
 		case BINDER_TYPE_BINDER:
 		case BINDER_TYPE_WEAK_BINDER: {
-			struct binder_node *node = binder_get_node(proc, fp->binder);
+			struct binder_node *node = binder_get_node(proc,
+								fp->binder);
 			if (node == NULL) {
-				printk(KERN_ERR "binder: transaction release %d"
+				binder_debug(BINDER_DEBUG_TOP_ERRORS,
+					"binder: transaction release %d"
 				       " bad node %p\n", debug_id, fp->binder);
 				break;
 			}
 			binder_debug(BINDER_DEBUG_TRANSACTION,
 				     "        node %d u%p\n",
 				     node->debug_id, node->ptr);
-			binder_dec_node(node, fp->type == BINDER_TYPE_BINDER, 0);
+			binder_dec_node(node, fp->type == BINDER_TYPE_BINDER,
+									0);
 		} break;
 		case BINDER_TYPE_HANDLE:
 		case BINDER_TYPE_WEAK_HANDLE: {
-			struct binder_ref *ref = binder_get_ref(proc, fp->handle);
+			struct binder_ref *ref = binder_get_ref(proc,
+								fp->handle);
 			if (ref == NULL) {
-				printk(KERN_ERR "binder: transaction release %d"
+				binder_debug(BINDER_DEBUG_TOP_ERRORS,
+					"binder: transaction release %d"
 				       " bad handle %ld\n", debug_id,
 				       fp->handle);
 				break;
 			}
 			binder_debug(BINDER_DEBUG_TRANSACTION,
 				     "        ref %d desc %d (node %d)\n",
-				     ref->debug_id, ref->desc, ref->node->debug_id);
+				     ref->debug_id, ref->desc,
+				     ref->node->debug_id);
 			binder_dec_ref(ref, fp->type == BINDER_TYPE_HANDLE);
 		} break;
 
@@ -1368,7 +1387,8 @@
 			break;
 
 		default:
-			printk(KERN_ERR "binder: transaction release %d bad "
+			binder_debug(BINDER_DEBUG_TOP_ERRORS,
+				"binder: transaction release %d bad "
 			       "object type %lx\n", debug_id, fp->type);
 			break;
 		}
@@ -1594,15 +1614,19 @@
 		case BINDER_TYPE_BINDER:
 		case BINDER_TYPE_WEAK_BINDER: {
 			struct binder_ref *ref;
-			struct binder_node *node = binder_get_node(proc, fp->binder);
+			struct binder_node *node = binder_get_node(proc,
+								fp->binder);
 			if (node == NULL) {
-				node = binder_new_node(proc, fp->binder, fp->cookie);
+				node = binder_new_node(proc, fp->binder,
+								fp->cookie);
 				if (node == NULL) {
 					return_error = BR_FAILED_REPLY;
 					goto err_binder_new_node_failed;
 				}
-				node->min_priority = fp->flags & FLAT_BINDER_FLAG_PRIORITY_MASK;
-				node->accept_fds = !!(fp->flags & FLAT_BINDER_FLAG_ACCEPTS_FDS);
+				node->min_priority = fp->flags &
+						FLAT_BINDER_FLAG_PRIORITY_MASK;
+				node->accept_fds = !!(fp->flags &
+						FLAT_BINDER_FLAG_ACCEPTS_FDS);
 			}
 			if (fp->cookie != node->cookie) {
 				binder_user_error("binder: %d:%d sending u%p "
@@ -1632,7 +1656,8 @@
 		} break;
 		case BINDER_TYPE_HANDLE:
 		case BINDER_TYPE_WEAK_HANDLE: {
-			struct binder_ref *ref = binder_get_ref(proc, fp->handle);
+			struct binder_ref *ref = binder_get_ref(proc,
+								fp->handle);
 			if (ref == NULL) {
 				binder_user_error("binder: %d:%d got "
 					"transaction with invalid "
@@ -1648,24 +1673,31 @@
 					fp->type = BINDER_TYPE_WEAK_BINDER;
 				fp->binder = ref->node->ptr;
 				fp->cookie = ref->node->cookie;
-				binder_inc_node(ref->node, fp->type == BINDER_TYPE_BINDER, 0, NULL);
+				binder_inc_node(ref->node, fp->type ==
+						BINDER_TYPE_BINDER, 0, NULL);
 				binder_debug(BINDER_DEBUG_TRANSACTION,
-					     "        ref %d desc %d -> node %d u%p\n",
-					     ref->debug_id, ref->desc, ref->node->debug_id,
-					     ref->node->ptr);
+				      "        ref %d desc %d -> node %d u%p\n",
+				     ref->debug_id, ref->desc,
+				    ref->node->debug_id,
+				     ref->node->ptr);
 			} else {
 				struct binder_ref *new_ref;
-				new_ref = binder_get_ref_for_node(target_proc, ref->node);
+				new_ref = binder_get_ref_for_node(target_proc,
+								ref->node);
 				if (new_ref == NULL) {
 					return_error = BR_FAILED_REPLY;
 					goto err_binder_get_ref_for_node_failed;
 				}
 				fp->handle = new_ref->desc;
-				binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL);
+				binder_inc_ref(new_ref, fp->type ==
+						BINDER_TYPE_HANDLE, NULL);
 				binder_debug(BINDER_DEBUG_TRANSACTION,
-					     "        ref %d desc %d -> ref %d desc %d (node %d)\n",
-					     ref->debug_id, ref->desc, new_ref->debug_id,
-					     new_ref->desc, ref->node->debug_id);
+					     "        ref %d desc %d -> ref %d"
+					     " desc %d (node %d)\n",
+					     ref->debug_id, ref->desc,
+					     new_ref->debug_id,
+					     new_ref->desc,
+					     ref->node->debug_id);
 			}
 		} break;
 
@@ -1675,13 +1707,19 @@
 
 			if (reply) {
 				if (!(in_reply_to->flags & TF_ACCEPT_FDS)) {
-					binder_user_error("binder: %d:%d got reply with fd, %ld, but target does not allow fds\n",
-						proc->pid, thread->pid, fp->handle);
+					binder_user_error("binder: %d:%d got"
+						" reply with fd, %ld, but"
+						" target does not allow fds\n",
+						proc->pid, thread->pid,
+						fp->handle);
 					return_error = BR_FAILED_REPLY;
 					goto err_fd_not_allowed;
 				}
 			} else if (!target_node->accept_fds) {
-				binder_user_error("binder: %d:%d got transaction with fd, %ld, but target does not allow fds\n",
+				binder_user_error(
+						"binder: %d:%d got transaction"
+						" with fd, %ld, but target does"
+						" not allow fds\n",
 					proc->pid, thread->pid, fp->handle);
 				return_error = BR_FAILED_REPLY;
 				goto err_fd_not_allowed;
@@ -1689,12 +1727,15 @@
 
 			file = fget(fp->handle);
 			if (file == NULL) {
-				binder_user_error("binder: %d:%d got transaction with invalid fd, %ld\n",
+				binder_user_error(
+						"binder: %d:%d got transaction"
+						" with invalid fd, %ld\n",
 					proc->pid, thread->pid, fp->handle);
 				return_error = BR_FAILED_REPLY;
 				goto err_fget_failed;
 			}
-			target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC);
+			target_fd = task_get_unused_fd_flags(target_proc,
+								O_CLOEXEC);
 			if (target_fd < 0) {
 				fput(file);
 				return_error = BR_FAILED_REPLY;
@@ -1702,7 +1743,8 @@
 			}
 			task_fd_install(target_proc, target_fd, file);
 			binder_debug(BINDER_DEBUG_TRANSACTION,
-				     "        fd %ld -> %d\n", fp->handle, target_fd);
+				     "        fd %ld -> %d\n", fp->handle,
+								target_fd);
 			/* TODO: fput? */
 			fp->handle = target_fd;
 		} break;
@@ -1851,9 +1893,11 @@
 				break;
 			}
 			binder_debug(BINDER_DEBUG_USER_REFS,
-				     "binder: %d:%d %s ref %d desc %d s %d w %d for node %d\n",
-				     proc->pid, thread->pid, debug_string, ref->debug_id,
-				     ref->desc, ref->strong, ref->weak, ref->node->debug_id);
+				     "binder: %d:%d %s ref %d desc %d s %d w %d"
+				     " for node %d\n", proc->pid, thread->pid,
+				     debug_string, ref->debug_id, ref->desc,
+				     ref->strong, ref->weak,
+				     ref->node->debug_id);
 			break;
 		}
 		case BC_INCREFS_DONE:
@@ -1914,15 +1958,19 @@
 			binder_debug(BINDER_DEBUG_USER_REFS,
 				     "binder: %d:%d %s node %d ls %d lw %d\n",
 				     proc->pid, thread->pid,
-				     cmd == BC_INCREFS_DONE ? "BC_INCREFS_DONE" : "BC_ACQUIRE_DONE",
-				     node->debug_id, node->local_strong_refs, node->local_weak_refs);
+				     cmd == BC_INCREFS_DONE ? "BC_INCREFS_DONE"
+							: "BC_ACQUIRE_DONE",
+				     node->debug_id, node->local_strong_refs,
+							node->local_weak_refs);
 			break;
 		}
 		case BC_ATTEMPT_ACQUIRE:
-			printk(KERN_ERR "binder: BC_ATTEMPT_ACQUIRE not supported\n");
+			binder_debug(BINDER_DEBUG_TOP_ERRORS,
+				"binder: BC_ATTEMPT_ACQUIRE not supported\n");
 			return -EINVAL;
 		case BC_ACQUIRE_RESULT:
-			printk(KERN_ERR "binder: BC_ACQUIRE_RESULT not supported\n");
+			binder_debug(BINDER_DEBUG_TOP_ERRORS,
+				"binder: BC_ACQUIRE_RESULT not supported\n");
 			return -EINVAL;
 
 		case BC_FREE_BUFFER: {
@@ -1948,9 +1996,11 @@
 				break;
 			}
 			binder_debug(BINDER_DEBUG_FREE_BUFFER,
-				     "binder: %d:%d BC_FREE_BUFFER u%p found buffer %d for %s transaction\n",
-				     proc->pid, thread->pid, data_ptr, buffer->debug_id,
-				     buffer->transaction ? "active" : "finished");
+				     "binder: %d:%d BC_FREE_BUFFER u%p found"
+				     " buffer %d for %s transaction\n",
+				     proc->pid, thread->pid, data_ptr,
+				     buffer->debug_id, buffer->transaction ?
+				     "active" : "finished");
 
 			if (buffer->transaction) {
 				buffer->transaction->buffer = NULL;
@@ -2047,13 +2097,15 @@
 			}
 
 			binder_debug(BINDER_DEBUG_DEATH_NOTIFICATION,
-				     "binder: %d:%d %s %p ref %d desc %d s %d w %d for node %d\n",
+				     "binder: %d:%d %s %p ref %d desc %d s %d"
+				     " w %d for node %d\n",
 				     proc->pid, thread->pid,
 				     cmd == BC_REQUEST_DEATH_NOTIFICATION ?
 				     "BC_REQUEST_DEATH_NOTIFICATION" :
 				     "BC_CLEAR_DEATH_NOTIFICATION",
 				     cookie, ref->debug_id, ref->desc,
-				     ref->strong, ref->weak, ref->node->debug_id);
+				     ref->strong, ref->weak,
+				     ref->node->debug_id);
 
 			if (cmd == BC_REQUEST_DEATH_NOTIFICATION) {
 				if (ref->death) {
@@ -2067,10 +2119,12 @@
 				death = kzalloc(sizeof(*death), GFP_KERNEL);
 				if (death == NULL) {
 					thread->return_error = BR_ERROR;
-					binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
-						     "binder: %d:%d "
-						     "BC_REQUEST_DEATH_NOTIFICATION failed\n",
-						     proc->pid, thread->pid);
+					binder_debug(
+						BINDER_DEBUG_FAILED_TRANSACTION,
+						"binder: %d:%d "
+						"BC_REQUEST_DEATH_NOTIFICATION"
+						" failed\n",
+						proc->pid, thread->pid);
 					break;
 				}
 				binder_stats_created(BINDER_STAT_DEATH);
@@ -2159,7 +2213,8 @@
 		} break;
 
 		default:
-			printk(KERN_ERR "binder: %d:%d unknown command %d\n",
+			binder_debug(BINDER_DEBUG_TOP_ERRORS,
+			      "binder: %d:%d unknown command %d\n",
 			       proc->pid, thread->pid, cmd);
 			return -EINVAL;
 		}
@@ -2629,9 +2684,11 @@
 	unsigned int size = _IOC_SIZE(cmd);
 	void __user *ubuf = (void __user *)arg;
 
-	/*printk(KERN_INFO "binder_ioctl: %d:%d %x %lx\n", proc->pid, current->pid, cmd, arg);*/
+	/*binder_debug(BINDER_DEBUG_TOP_ERRORS, "binder_ioctl: %d:%d %x %lx\n",
+					proc->pid, current->pid, cmd, arg);*/
 
-	ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
+	ret = wait_event_interruptible(binder_user_error_wait,
+						binder_stop_on_user_error < 2);
 	if (ret)
 		return ret;
 
@@ -2688,20 +2745,23 @@
 		break;
 	}
 	case BINDER_SET_MAX_THREADS:
-		if (copy_from_user(&proc->max_threads, ubuf, sizeof(proc->max_threads))) {
+		if (copy_from_user(&proc->max_threads, ubuf,
+					sizeof(proc->max_threads))) {
 			ret = -EINVAL;
 			goto err;
 		}
 		break;
 	case BINDER_SET_CONTEXT_MGR:
 		if (binder_context_mgr_node != NULL) {
-			printk(KERN_ERR "binder: BINDER_SET_CONTEXT_MGR already set\n");
+			binder_debug(BINDER_DEBUG_TOP_ERRORS,
+				"binder: BINDER_SET_CONTEXT_MGR already set\n");
 			ret = -EBUSY;
 			goto err;
 		}
 		if (binder_context_mgr_uid != -1) {
 			if (binder_context_mgr_uid != current->cred->euid) {
-				printk(KERN_ERR "binder: BINDER_SET_"
+				binder_debug(BINDER_DEBUG_TOP_ERRORS,
+				       "binder: BINDER_SET_"
 				       "CONTEXT_MGR bad uid %d != %d\n",
 				       current->cred->euid,
 				       binder_context_mgr_uid);
@@ -2747,7 +2807,9 @@
 	mutex_unlock(&binder_lock);
 	wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
 	if (ret && ret != -ERESTARTSYS)
-		printk(KERN_INFO "binder: %d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret);
+		binder_debug(BINDER_DEBUG_TOP_ERRORS,
+				"binder: %d:%d ioctl %x %lx returned %d\n",
+				proc->pid, current->pid, cmd, arg, ret);
 	return ret;
 }
 
@@ -2821,7 +2883,9 @@
 #ifdef CONFIG_CPU_CACHE_VIPT
 	if (cache_is_vipt_aliasing()) {
 		while (CACHE_COLOUR((vma->vm_start ^ (uint32_t)proc->buffer))) {
-			printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p bad alignment\n", proc->pid, vma->vm_start, vma->vm_end, proc->buffer);
+			binder_debug(BINDER_DEBUG_TOP_ERRORS,
+			"binder_mmap: %d %lx-%lx maps %p bad alignment\n",
+			proc->pid, vma->vm_start, vma->vm_end, proc->buffer);
 			vma->vm_start += PAGE_SIZE;
 		}
 	}
@@ -2852,7 +2916,8 @@
 	proc->files = get_files_struct(current);
 	proc->vma = vma;
 
-	/*printk(KERN_INFO "binder_mmap: %d %lx-%lx maps %p\n",
+	/*binder_debug(BINDER_DEBUG_TOP_ERRORS,
+		"binder_mmap: %d %lx-%lx maps %p\n",
 		 proc->pid, vma->vm_start, vma->vm_end, proc->buffer);*/
 	return 0;
 
@@ -2865,7 +2930,8 @@
 err_get_vm_area_failed:
 err_already_mapped:
 err_bad_arg:
-	printk(KERN_ERR "binder_mmap: %d %lx-%lx %s failed %d\n",
+	binder_debug(BINDER_DEBUG_TOP_ERRORS,
+		"binder_mmap: %d %lx-%lx %s failed %d\n",
 	       proc->pid, vma->vm_start, vma->vm_end, failure_string, ret);
 	return ret;
 }
@@ -3020,7 +3086,8 @@
 		if (t) {
 			t->buffer = NULL;
 			buffer->transaction = NULL;
-			printk(KERN_ERR "binder: release proc %d, "
+			binder_debug(BINDER_DEBUG_TOP_ERRORS,
+				"binder: release proc %d, "
 			       "transaction %d, not freed\n",
 			       proc->pid, t->debug_id);
 			/*BUG();*/
diff --git a/drivers/staging/qcache/qcache-main.c b/drivers/staging/qcache/qcache-main.c
index b6de268..f6838d1 100644
--- a/drivers/staging/qcache/qcache-main.c
+++ b/drivers/staging/qcache/qcache-main.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2010,2011, Dan Magenheimer, Oracle Corp.
  * Copyright (c) 2010,2011, Nitin Gupta
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * Qcache provides an in-kernel "host implementation" for transcendent memory
  * and, thus indirectly, for cleancache and frontswap.  Qcache includes a
@@ -230,7 +230,6 @@
 	budnum = zbud_budnum(zh);
 	BUG_ON(size == 0 || size > zbud_max_buddy_size());
 	zbpg = container_of(zh, struct zbud_page, buddy[budnum]);
-	ASSERT_SPINLOCK(&zbpg->lock);
 	p = (char *)zbpg;
 	if (budnum == 0)
 		p += ((sizeof(struct zbud_page) + CHUNK_SIZE - 1) &
@@ -270,7 +269,6 @@
 
 	ASSERT_SENTINEL(zbpg, ZBPG);
 	BUG_ON(!list_empty(&zbpg->bud_list));
-	ASSERT_SPINLOCK(&zbpg->lock);
 	BUG_ON(zh0->size != 0 || tmem_oid_valid(&zh0->oid));
 	BUG_ON(zh1->size != 0 || tmem_oid_valid(&zh1->oid));
 	INVERT_SENTINEL(zbpg, ZBPG);
@@ -312,7 +310,6 @@
 		return;
 	}
 	size = zbud_free(zh);
-	ASSERT_SPINLOCK(&zbpg->lock);
 	zh_other = &zbpg->buddy[(budnum == 0) ? 1 : 0];
 	if (zh_other->size == 0) { /* was unbuddied: unlist and free */
 		chunks = zbud_size_to_chunks(size) ;
@@ -372,7 +369,6 @@
 	goto init_zh;
 
 found_unbuddied:
-	ASSERT_SPINLOCK(&zbpg->lock);
 	zh0 = &zbpg->buddy[0]; zh1 = &zbpg->buddy[1];
 	BUG_ON(!((zh0->size == 0) ^ (zh1->size == 0)));
 	if (zh0->size != 0) { /* buddy0 in use, buddy1 is vacant */
diff --git a/drivers/staging/qcache/tmem.h b/drivers/staging/qcache/tmem.h
index 344561f..9f6bfbb 100644
--- a/drivers/staging/qcache/tmem.h
+++ b/drivers/staging/qcache/tmem.h
@@ -4,7 +4,7 @@
  * Transcendent memory
  *
  * Copyright (c) 2009-2011, Dan Magenheimer, Oracle Corp.
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  */
 
 #ifndef _TMEM_H_
@@ -49,8 +49,6 @@
 #define ASSERT_INVERTED_SENTINEL(_x, _y) do { } while (0)
 #endif
 
-#define ASSERT_SPINLOCK(_l)	WARN_ON(!spin_is_locked(_l))
-
 /*
  * A pool is the highest-level data structure managed by tmem and
  * usually corresponds to a large independent set of pages such as
diff --git a/drivers/usb/gadget/f_diag.c b/drivers/usb/gadget/f_diag.c
index f492143..10a9256 100644
--- a/drivers/usb/gadget/f_diag.c
+++ b/drivers/usb/gadget/f_diag.c
@@ -2,7 +2,7 @@
  * Diag Function Device - Route ARM9 and ARM11 DIAG messages
  * between HOST and DEVICE.
  * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -525,6 +525,7 @@
 	if (rc) {
 		ERROR(dev->cdev, "can't enable %s, result %d\n",
 						dev->in->name, rc);
+		dev->in->driver_data = NULL;
 		return rc;
 	}
 	dev->out->driver_data = dev;
@@ -533,6 +534,8 @@
 		ERROR(dev->cdev, "can't enable %s, result %d\n",
 						dev->out->name, rc);
 		usb_ep_disable(dev->in);
+		dev->in->driver_data = NULL;
+		dev->out->driver_data = NULL;
 		return rc;
 	}
 	schedule_work(&dev->config_work);
diff --git a/drivers/usb/gadget/f_rmnet.c b/drivers/usb/gadget/f_rmnet.c
index cbcf5ac..177176e 100644
--- a/drivers/usb/gadget/f_rmnet.c
+++ b/drivers/usb/gadget/f_rmnet.c
@@ -1,5 +1,5 @@
 /*
- * 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
@@ -435,6 +435,7 @@
 	pr_debug("%s: port#%d\n", __func__, dev->port_num);
 
 	usb_ep_disable(dev->notify);
+	dev->notify->driver_data = NULL;
 
 	atomic_set(&dev->online, 0);
 
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c
index de8c8ed..d9a901b 100644
--- a/drivers/usb/gadget/f_serial.c
+++ b/drivers/usb/gadget/f_serial.c
@@ -477,6 +477,7 @@
 	if (gser->notify->driver_data) {
 		DBG(cdev, "reset generic ctl ttyGS%d\n", gser->port_num);
 		usb_ep_disable(gser->notify);
+		gser->notify->driver_data = NULL;
 	}
 	gser->notify_desc = ep_choose(cdev->gadget,
 			gser->hs.notify,
@@ -519,6 +520,7 @@
 #ifdef CONFIG_MODEM_SUPPORT
 	usb_ep_fifo_flush(gser->notify);
 	usb_ep_disable(gser->notify);
+	gser->notify->driver_data = NULL;
 #endif
 	gser->online = 0;
 }
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index 0360f56..ca298cd 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -2766,14 +2766,17 @@
 	if (fsg->bulk_in_enabled) {
 		usb_ep_disable(fsg->bulk_in);
 		fsg->bulk_in_enabled = 0;
+		fsg_bulk_in->driver_data = NULL;
 	}
 	if (fsg->bulk_out_enabled) {
 		usb_ep_disable(fsg->bulk_out);
 		fsg->bulk_out_enabled = 0;
+		fsg_bulk_out->driver_data = NULL;
 	}
 	if (fsg->intr_in_enabled) {
 		usb_ep_disable(fsg->intr_in);
 		fsg->intr_in_enabled = 0;
+		fsg_intr_in->driver_data = NULL;
 	}
 
 	fsg->running = 0;
diff --git a/drivers/usb/gadget/u_bam.c b/drivers/usb/gadget/u_bam.c
index 13965de..23e0da8 100644
--- a/drivers/usb/gadget/u_bam.c
+++ b/drivers/usb/gadget/u_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
@@ -602,7 +602,7 @@
 	struct bam_ch_info	*d;
 
 	spin_lock_irqsave(&port->port_lock_ul, flags);
-	spin_lock_irqsave(&port->port_lock_dl, flags);
+	spin_lock(&port->port_lock_dl);
 
 	if (!port || !port->port_usb)
 		goto free_buf_out;
@@ -619,7 +619,7 @@
 		dev_kfree_skb_any(skb);
 
 free_buf_out:
-	spin_unlock_irqrestore(&port->port_lock_dl, flags);
+	spin_unlock(&port->port_lock_dl);
 	spin_unlock_irqrestore(&port->port_lock_ul, flags);
 }
 
@@ -643,15 +643,17 @@
 	unsigned long		flags;
 
 	spin_lock_irqsave(&port->port_lock_ul, flags);
-	spin_lock_irqsave(&port->port_lock_dl, flags);
+	spin_lock(&port->port_lock_dl);
 	port->port_usb = 0;
-	spin_unlock_irqrestore(&port->port_lock_dl, flags);
+	spin_unlock(&port->port_lock_dl);
 	spin_unlock_irqrestore(&port->port_lock_ul, flags);
 
 	/* disable endpoints */
 	usb_ep_disable(port->gr->out);
 	usb_ep_disable(port->gr->in);
 
+	port->gr->in->driver_data = NULL;
+	port->gr->out->driver_data = NULL;
 }
 
 static void gbam_connect_work(struct work_struct *w)
@@ -662,13 +664,13 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&port->port_lock_ul, flags);
-	spin_lock_irqsave(&port->port_lock_dl, flags);
+	spin_lock(&port->port_lock_dl);
 	if (!port->port_usb) {
-		spin_unlock_irqrestore(&port->port_lock_dl, flags);
+		spin_unlock(&port->port_lock_dl);
 		spin_unlock_irqrestore(&port->port_lock_ul, flags);
 		return;
 	}
-	spin_unlock_irqrestore(&port->port_lock_dl, flags);
+	spin_unlock(&port->port_lock_dl);
 	spin_unlock_irqrestore(&port->port_lock_ul, flags);
 
 	if (!test_bit(BAM_CH_READY, &d->flags))
@@ -712,9 +714,9 @@
 	}
 	port->gr->out->driver_data = port;
 	spin_lock_irqsave(&port->port_lock_ul, flags);
-	spin_lock_irqsave(&port->port_lock_dl, flags);
+	spin_lock(&port->port_lock_dl);
 	port->port_usb = port->gr;
-	spin_unlock_irqrestore(&port->port_lock_dl, flags);
+	spin_unlock(&port->port_lock_dl);
 	spin_unlock_irqrestore(&port->port_lock_ul, flags);
 
 	ret = usb_bam_connect(d->connection_idx, &d->src_pipe_idx,
@@ -773,10 +775,10 @@
 
 			/* if usb is online, try opening bam_ch */
 			spin_lock_irqsave(&port->port_lock_ul, flags);
-			spin_lock_irqsave(&port->port_lock_dl, flags);
+			spin_lock(&port->port_lock_dl);
 			if (port->port_usb)
 				queue_work(gbam_wq, &port->connect_w);
-			spin_unlock_irqrestore(&port->port_lock_dl, flags);
+			spin_unlock(&port->port_lock_dl);
 			spin_unlock_irqrestore(&port->port_lock_ul, flags);
 
 			break;
@@ -805,12 +807,12 @@
 			d = &port->data_ch;
 
 			spin_lock_irqsave(&port->port_lock_ul, flags);
-			spin_lock_irqsave(&port->port_lock_dl, flags);
+			spin_lock(&port->port_lock_dl);
 			if (port->port_usb) {
 				ep_in = port->port_usb->in;
 				ep_out = port->port_usb->out;
 			}
-			spin_unlock_irqrestore(&port->port_lock_dl, flags);
+			spin_unlock(&port->port_lock_dl);
 			spin_unlock_irqrestore(&port->port_lock_ul, flags);
 
 			if (ep_in)
@@ -944,7 +946,7 @@
 		if (!port)
 			continue;
 		spin_lock_irqsave(&port->port_lock_ul, flags);
-		spin_lock_irqsave(&port->port_lock_dl, flags);
+		spin_lock(&port->port_lock_dl);
 
 		d = &port->data_ch;
 
@@ -967,7 +969,7 @@
 				test_bit(BAM_CH_OPENED, &d->flags),
 				test_bit(BAM_CH_READY, &d->flags));
 
-		spin_unlock_irqrestore(&port->port_lock_dl, flags);
+		spin_unlock(&port->port_lock_dl);
 		spin_unlock_irqrestore(&port->port_lock_ul, flags);
 	}
 
@@ -992,7 +994,7 @@
 			continue;
 
 		spin_lock_irqsave(&port->port_lock_ul, flags);
-		spin_lock_irqsave(&port->port_lock_dl, flags);
+		spin_lock(&port->port_lock_dl);
 
 		d = &port->data_ch;
 
@@ -1002,7 +1004,7 @@
 		d->tohost_drp_cnt = 0;
 		d->tomodem_drp_cnt = 0;
 
-		spin_unlock_irqrestore(&port->port_lock_dl, flags);
+		spin_unlock(&port->port_lock_dl);
 		spin_unlock_irqrestore(&port->port_lock_ul, flags);
 	}
 	return count;
@@ -1069,10 +1071,10 @@
 		gbam_free_buffers(port);
 
 	spin_lock_irqsave(&port->port_lock_ul, flags);
-	spin_lock_irqsave(&port->port_lock_dl, flags);
+	spin_lock(&port->port_lock_dl);
 	port->port_usb = 0;
 	n_tx_req_queued = 0;
-	spin_unlock_irqrestore(&port->port_lock_dl, flags);
+	spin_unlock(&port->port_lock_dl);
 	spin_unlock_irqrestore(&port->port_lock_ul, flags);
 
 		/* disable endpoints */
@@ -1134,7 +1136,7 @@
 		gr->out->driver_data = port;
 
 	spin_lock_irqsave(&port->port_lock_ul, flags);
-	spin_lock_irqsave(&port->port_lock_dl, flags);
+	spin_lock(&port->port_lock_dl);
 	port->port_usb = gr;
 
 		d->to_host = 0;
@@ -1142,7 +1144,7 @@
 		d->pending_with_bam = 0;
 		d->tohost_drp_cnt = 0;
 		d->tomodem_drp_cnt = 0;
-	spin_unlock_irqrestore(&port->port_lock_dl, flags);
+	spin_unlock(&port->port_lock_dl);
 	spin_unlock_irqrestore(&port->port_lock_ul, flags);
 	}
 
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 1066f38..ec9ac24 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -1713,11 +1713,12 @@
 			else
 				clear_bit(B_SESS_VLD, &motg->inputs);
 		} else if (pdata->otg_control == OTG_PMIC_CONTROL) {
-			if (irq_read_line(motg->pdata->pmic_id_irq))
-				set_bit(ID, &motg->inputs);
-			else
-				clear_bit(ID, &motg->inputs);
-
+			if (pdata->pmic_id_irq) {
+				if (irq_read_line(pdata->pmic_id_irq))
+					set_bit(ID, &motg->inputs);
+				else
+					clear_bit(ID, &motg->inputs);
+			}
 			/*
 			 * VBUS initial state is reported after PMIC
 			 * driver initialization. Wait for it.
@@ -1730,10 +1731,18 @@
 		break;
 	case USB_PERIPHERAL:
 		set_bit(ID, &motg->inputs);
-		if (otgsc & OTGSC_BSV)
-			set_bit(B_SESS_VLD, &motg->inputs);
-		else
-			clear_bit(B_SESS_VLD, &motg->inputs);
+		if (pdata->otg_control == OTG_PHY_CONTROL) {
+			if (otgsc & OTGSC_BSV)
+				set_bit(B_SESS_VLD, &motg->inputs);
+			else
+				clear_bit(B_SESS_VLD, &motg->inputs);
+		} else if (pdata->otg_control == OTG_PMIC_CONTROL) {
+			/*
+			 * VBUS initial state is reported after PMIC
+			 * driver initialization. Wait for it.
+			 */
+			wait_for_completion(&pmic_vbus_init);
+		}
 		break;
 	default:
 		break;
@@ -2511,7 +2520,8 @@
 		goto free_irq;
 	}
 
-	if (motg->pdata->otg_control == OTG_PMIC_CONTROL) {
+	if (motg->pdata->mode == USB_OTG &&
+		motg->pdata->otg_control == OTG_PMIC_CONTROL) {
 		if (motg->pdata->pmic_id_irq) {
 			ret = request_irq(motg->pdata->pmic_id_irq,
 						msm_pmic_id_irq,
@@ -2545,7 +2555,8 @@
 
 	if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY) {
 		if (motg->pdata->otg_control == OTG_PMIC_CONTROL &&
-			motg->pdata->pmic_id_irq)
+			(!(motg->pdata->mode == USB_OTG) ||
+			 motg->pdata->pmic_id_irq))
 			motg->caps = ALLOW_PHY_POWER_COLLAPSE |
 				ALLOW_PHY_RETENTION |
 				ALLOW_PHY_COMP_DISABLE;
diff --git a/drivers/video/msm/external_common.h b/drivers/video/msm/external_common.h
index c795a94..2a243cd 100644
--- a/drivers/video/msm/external_common.h
+++ b/drivers/video/msm/external_common.h
@@ -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
@@ -136,10 +136,10 @@
 	 480, 10, 2, 33, TRUE, 25200, 60000, FALSE, TRUE}
 #define HDMI_SETTINGS_720x480p60_4_3					\
 	{HDMI_VFRMT_720x480p60_4_3,      720,  16,  62,  60,  TRUE,	\
-	 480, 9, 6, 30,  TRUE, 27027, 60000, FALSE, TRUE}
+	 480, 9, 6, 30,  TRUE, 27030, 60000, FALSE, TRUE}
 #define HDMI_SETTINGS_720x480p60_16_9					\
 	{HDMI_VFRMT_720x480p60_16_9,     720,  16,  62,  60,  TRUE,	\
-	 480, 9, 6, 30,  TRUE, 27027, 60000, FALSE, TRUE}
+	 480, 9, 6, 30,  TRUE, 27030, 60000, FALSE, TRUE}
 #define HDMI_SETTINGS_1280x720p60_16_9					\
 	{HDMI_VFRMT_1280x720p60_16_9,    1280, 110, 40,  220, FALSE,	\
 	 720, 5, 5, 20, FALSE, 74250, 60000, FALSE, TRUE}
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index aaad2df..60a40b2 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.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
@@ -3073,7 +3073,7 @@
 		{4096, 27000}, {6272, 30000}, {6144, 27000}, {12544, 30000},
 		{12288, 27000}, {25088, 30000}, {24576, 27000} }),
 	/*  27.027MHz */
-	HDMI_MSM_AUDIO_ARCS(27027, {
+	HDMI_MSM_AUDIO_ARCS(27030, {
 		{4096, 27027}, {6272, 30030}, {6144, 27027}, {12544, 30030},
 		{12288, 27027}, {25088, 30030}, {24576, 27027} }),
 	/*  74.250MHz */
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index 645a0c3..ecb0a24 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -418,6 +418,7 @@
 	char *rgb_base;
 	uint32 src_size, src_xy, dst_size, dst_xy;
 	uint32 format, pattern;
+	uint32 offset = 0;
 
 	rgb_base = MDP_BASE + MDP4_RGB_BASE;
 	rgb_base += (MDP4_RGB_OFF * pipe->pipe_num);
@@ -427,6 +428,16 @@
 	dst_size = ((pipe->dst_h << 16) | pipe->dst_w);
 	dst_xy = ((pipe->dst_y << 16) | pipe->dst_x);
 
+	if ((pipe->src_x + pipe->src_w) > 0x7FF) {
+		offset += pipe->src_x * pipe->bpp;
+		src_xy &= 0xFFFF0000;
+	}
+
+	if ((pipe->src_y + pipe->src_h) > 0x7FF) {
+		offset += pipe->src_y * pipe->src_width * pipe->bpp;
+		src_xy &= 0x0000FFFF;
+	}
+
 	format = mdp4_overlay_format(pipe);
 	pattern = mdp4_overlay_unpack_pattern(pipe);
 
@@ -443,7 +454,7 @@
 	outpdw(rgb_base + 0x0008, dst_size);	/* MDP_RGB_DST_SIZE */
 	outpdw(rgb_base + 0x000c, dst_xy);	/* MDP_RGB_DST_XY */
 
-	outpdw(rgb_base + 0x0010, pipe->srcp0_addr);
+	outpdw(rgb_base + 0x0010, pipe->srcp0_addr + offset);
 	outpdw(rgb_base + 0x0040, pipe->srcp0_ystride);
 
 	outpdw(rgb_base + 0x0050, format);/* MDP_RGB_SRC_FORMAT */
@@ -548,6 +559,21 @@
 
 	mdp4_scale_setup(pipe);
 
+	luma_offset = 0;
+	chroma_offset = 0;
+
+	if (ptype == OVERLAY_TYPE_RGB) {
+		if ((pipe->src_y + pipe->src_h) > 0x7FF) {
+			luma_offset = pipe->src_y * pipe->src_width * pipe->bpp;
+			src_xy &= 0x0000FFFF;
+		}
+
+		if ((pipe->src_x + pipe->src_w) > 0x7FF) {
+			luma_offset += pipe->src_x * pipe->bpp;
+			src_xy &= 0xFFFF0000;
+		}
+	}
+
 	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
 
 	outpdw(vg_base + 0x0000, src_size);	/* MDP_RGB_SRC_SIZE */
@@ -567,9 +593,6 @@
 	if (ptype != OVERLAY_TYPE_RGB) {
 		mdp4_overlay_vg_get_src_offset(pipe, vg_base, &luma_offset,
 			&chroma_offset);
-	} else {
-		luma_offset = 0;
-		chroma_offset = 0;
 	}
 
 	/* luma component plane */
@@ -1804,8 +1827,8 @@
 
 	}
 
-	pipe->src_width = req->src.width & 0x07ff;	/* source img width */
-	pipe->src_height = req->src.height & 0x07ff;	/* source img height */
+	pipe->src_width = req->src.width & 0x1fff;	/* source img width */
+	pipe->src_height = req->src.height & 0x1fff;	/* source img height */
 	pipe->src_h = req->src_rect.h & 0x07ff;
 	pipe->src_w = req->src_rect.w & 0x07ff;
 	pipe->src_y = req->src_rect.y & 0x07ff;
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index a905ec0..5ad6de3f 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -451,6 +451,29 @@
 	complete(&dma->comp);
 }
 
+static void mdp4_overlay_lcdc_prefill(struct msm_fb_data_type *mfd)
+{
+	unsigned long flag;
+
+	if (lcdc_pipe->blt_addr) {
+		mdp4_overlay_lcdc_dma_busy_wait(mfd);
+
+		mdp4_lcdc_blt_ov_update(lcdc_pipe);
+		lcdc_pipe->ov_cnt++;
+
+		spin_lock_irqsave(&mdp_spin_lock, flag);
+		outp32(MDP_INTR_CLEAR, INTR_OVERLAY0_DONE);
+		mdp_intr_mask |= INTR_OVERLAY0_DONE;
+		outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+		mdp_enable_irq(MDP_OVERLAY0_TERM);
+		mfd->dma->busy = TRUE;
+		mb();	/* make sure all registers updated */
+		spin_unlock_irqrestore(&mdp_spin_lock, flag);
+		outpdw(MDP_BASE + 0x0004, 0); /* kickoff overlay engine */
+		mdp4_stat.kickoff_ov0++;
+		mb();
+	}
+}
 /*
  * make sure the MIPI_DSI_WRITEBACK_SIZE defined at boardfile
  * has enough space h * w * 3 * 2
@@ -490,6 +513,10 @@
 	msleep(20);
 	mdp4_overlayproc_cfg(lcdc_pipe);
 	mdp4_overlay_dmap_xy(lcdc_pipe);
+	if (lcdc_pipe->blt_addr) {
+		mdp4_overlay_lcdc_prefill(mfd);
+		mdp4_overlay_lcdc_prefill(mfd);
+	}
 	MDP_OUTP(MDP_BASE + LCDC_BASE, 1);	/* start lcdc */
 }
 
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 6025139..89ccbb9 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -2556,6 +2556,7 @@
 	int	ret;
 	struct msmfb_overlay_data req;
 	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+	struct msm_fb_panel_data *pdata;
 
 	if (mfd->overlay_play_enable == 0)	/* nothing to do */
 		return 0;
@@ -2579,6 +2580,19 @@
 
 	ret = mdp4_overlay_play(info, &req);
 
+	if (unset_bl_level && !bl_updated) {
+		pdata = (struct msm_fb_panel_data *)mfd->pdev->
+			dev.platform_data;
+		if ((pdata) && (pdata->set_backlight)) {
+			down(&mfd->sem);
+			mfd->bl_level = unset_bl_level;
+			pdata->set_backlight(mfd);
+			bl_level_old = unset_bl_level;
+			up(&mfd->sem);
+		}
+		bl_updated = 1;
+	}
+
 	return ret;
 }
 
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
index f69a471..7ccf4c2 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.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
@@ -24,8 +24,6 @@
 static struct time_data proc_time[MAX_TIME_DATA];
 #define DDL_MSG_TIME(x...) printk(KERN_DEBUG x)
 
-#define DDL_FW_CHANGE_ENDIAN
-
 static unsigned int vidc_mmu_subsystem[] =	{
 		MSM_SUBSYSTEM_VIDEO, MSM_SUBSYSTEM_VIDEO_FWARE};
 
@@ -65,7 +63,7 @@
 		}
 		addr->alloc_handle = ion_alloc(
 		ddl_context->video_ion_client, alloc_size, SZ_4K,
-			(1<<res_trk_get_mem_type()));
+			res_trk_get_mem_type());
 		if (IS_ERR_OR_NULL(addr->alloc_handle)) {
 			DDL_MSG_ERROR("%s() :DDL ION alloc failed\n",
 						 __func__);
@@ -289,23 +287,6 @@
 }
 #endif
 
-#ifdef DDL_FW_CHANGE_ENDIAN
-static void ddl_fw_change_endian(u8 *fw, u32 fw_size)
-{
-	u32 i = 0;
-	u8  temp;
-	for (i = 0; i < fw_size; i = i + 4) {
-		temp = fw[i];
-		fw[i] = fw[i+3];
-		fw[i+3] = temp;
-		temp = fw[i+1];
-		fw[i+1] = fw[i+2];
-		fw[i+2] = temp;
-	}
-	return;
-}
-#endif
-
 u32 ddl_fw_init(struct ddl_buf_addr *dram_base)
 {
 
@@ -319,9 +300,6 @@
 		vidc_video_codec_fw_size);
 	memcpy(dest_addr, vidc_video_codec_fw,
 		vidc_video_codec_fw_size);
-#ifdef DDL_FW_CHANGE_ENDIAN
-	ddl_fw_change_endian(dest_addr, vidc_video_codec_fw_size);
-#endif
 	return true;
 }
 
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
index 9c2e5d1..795d1e3 100644
--- a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
@@ -28,16 +28,152 @@
 static unsigned int vidc_clk_table[3] = {
 	48000000, 133330000, 200000000
 };
+static unsigned int restrk_mmu_subsystem[] =	{
+		MSM_SUBSYSTEM_VIDEO, MSM_SUBSYSTEM_VIDEO_FWARE};
 static struct res_trk_context resource_context;
 
 #define VIDC_FW	"vidc_1080p.fw"
 #define VIDC_FW_SIZE SZ_1M
 
+struct res_trk_vidc_mmu_clk {
+	char *mmu_clk_name;
+	struct clk *mmu_clk;
+};
+
+static struct res_trk_vidc_mmu_clk vidc_mmu_clks[] = {
+	{"mdp_iommu_clk"}, {"rot_iommu_clk"},
+	{"vcodec_iommu0_clk"}, {"vcodec_iommu1_clk"},
+	{"smmu_iface_clk"}
+};
+
 unsigned char *vidc_video_codec_fw;
 u32 vidc_video_codec_fw_size;
 static u32 res_trk_get_clk(void);
 static void res_trk_put_clk(void);
 
+static void *res_trk_pmem_map
+	(struct ddl_buf_addr *addr, size_t sz, u32 alignment)
+{
+	u32 offset = 0, flags = 0;
+	u32 index = 0;
+	struct ddl_context *ddl_context;
+	struct msm_mapped_buffer *mapped_buffer = NULL;
+	ddl_context = ddl_get_context();
+	if (!addr->alloced_phys_addr) {
+		pr_err(" %s() alloced addres NULL", __func__);
+		goto bail_out;
+	}
+	flags = MSM_SUBSYSTEM_MAP_IOVA | MSM_SUBSYSTEM_MAP_KADDR;
+	if (alignment == DDL_KILO_BYTE(128))
+			index = 1;
+	else if (alignment > SZ_4K)
+		flags |= MSM_SUBSYSTEM_ALIGN_IOVA_8K;
+
+	addr->mapped_buffer =
+	msm_subsystem_map_buffer((unsigned long)addr->alloced_phys_addr,
+	sz, flags, &restrk_mmu_subsystem[index],
+	sizeof(restrk_mmu_subsystem[index])/sizeof(unsigned int));
+	if (IS_ERR(addr->mapped_buffer)) {
+		pr_err(" %s() buffer map failed", __func__);
+		goto bail_out;
+	}
+	mapped_buffer = addr->mapped_buffer;
+	if (!mapped_buffer->vaddr || !mapped_buffer->iova[0]) {
+		pr_err("%s() map buffers failed\n", __func__);
+		goto bail_out;
+	}
+	addr->physical_base_addr = (u8 *)mapped_buffer->iova[0];
+	addr->virtual_base_addr = mapped_buffer->vaddr;
+	addr->align_physical_addr = (u8 *) DDL_ALIGN((u32)
+		addr->physical_base_addr, alignment);
+	offset = (u32)(addr->align_physical_addr -
+			addr->physical_base_addr);
+	addr->align_virtual_addr = addr->virtual_base_addr + offset;
+	addr->buffer_size = sz;
+	return addr->virtual_base_addr;
+bail_out:
+	return NULL;
+}
+
+static void *res_trk_pmem_alloc
+	(struct ddl_buf_addr *addr, size_t sz, u32 alignment)
+{
+	u32 alloc_size;
+	struct ddl_context *ddl_context;
+	int rc = -EINVAL;
+	ion_phys_addr_t phyaddr = 0;
+	size_t len = 0;
+	DBG_PMEM("\n%s() IN: Requested alloc size(%u)", __func__, (u32)sz);
+	if (!addr) {
+		DDL_MSG_ERROR("\n%s() Invalid Parameters", __func__);
+		goto bail_out;
+	}
+	ddl_context = ddl_get_context();
+	res_trk_set_mem_type(addr->mem_type);
+	alloc_size = (sz + alignment);
+	if (res_trk_get_enable_ion()) {
+		if (!ddl_context->video_ion_client)
+			ddl_context->video_ion_client =
+				res_trk_get_ion_client();
+		if (!ddl_context->video_ion_client) {
+			DDL_MSG_ERROR("%s() :DDL ION Client Invalid handle\n",
+						 __func__);
+			goto bail_out;
+		}
+		addr->alloc_handle = ion_alloc(
+		ddl_context->video_ion_client, alloc_size, SZ_4K,
+			res_trk_get_mem_type());
+		if (IS_ERR_OR_NULL(addr->alloc_handle)) {
+			DDL_MSG_ERROR("%s() :DDL ION alloc failed\n",
+						 __func__);
+			goto bail_out;
+		}
+		rc = ion_phys(ddl_context->video_ion_client,
+				addr->alloc_handle, &phyaddr,
+				 &len);
+		if (rc || !phyaddr) {
+			DDL_MSG_ERROR("%s():DDL ION client physical failed\n",
+						 __func__);
+			goto free_acm_ion_alloc;
+		}
+		addr->alloced_phys_addr = phyaddr;
+	} else {
+		addr->alloced_phys_addr = (phys_addr_t)
+		allocate_contiguous_memory_nomap(alloc_size,
+			res_trk_get_mem_type(), SZ_4K);
+		if (!addr->alloced_phys_addr) {
+			DDL_MSG_ERROR("%s() : acm alloc failed (%d)\n",
+					 __func__, alloc_size);
+			goto bail_out;
+		}
+	}
+
+	addr->buffer_size = sz;
+	return (void *)addr->alloced_phys_addr;
+
+free_acm_ion_alloc:
+	if (ddl_context->video_ion_client) {
+		if (addr->alloc_handle) {
+			ion_free(ddl_context->video_ion_client,
+				addr->alloc_handle);
+			addr->alloc_handle = NULL;
+		}
+	}
+bail_out:
+	return NULL;
+}
+
+static void res_trk_pmem_unmap(struct ddl_buf_addr *addr)
+{
+	if (!addr) {
+		pr_err("%s() invalid args\n", __func__);
+		return;
+	}
+	if (addr->mapped_buffer)
+		msm_subsystem_unmap_buffer(addr->mapped_buffer);
+	addr->mapped_buffer = NULL;
+}
+
 static u32 res_trk_get_clk()
 {
 	if (resource_context.vcodec_clk ||
@@ -252,6 +388,7 @@
 u32 res_trk_power_down(void)
 {
 	VCDRES_MSG_LOW("clk_regime_rail_disable");
+	res_trk_pmem_unmap(&resource_context.firmware_addr);
 #ifdef CONFIG_MSM_BUS_SCALING
 	msm_bus_scale_client_update_request(resource_context.pcl, 0);
 	msm_bus_scale_unregister_client(resource_context.pcl);
@@ -299,7 +436,6 @@
 
 	if (dev_ctxt->reqd_perf_lvl + dev_ctxt->curr_perf_lvl == 0)
 		bus_clk_index = 2;
-
 	bus_clk_index = (bus_clk_index << 1) + (client_type + 1);
 	VCDRES_MSG_LOW("%s(), bus_clk_index = %d", __func__, bus_clk_index);
 	VCDRES_MSG_LOW("%s(),context.pcl = %x", __func__, resource_context.pcl);
@@ -415,6 +551,7 @@
 	} else {
 		memset(&resource_context, 0, sizeof(resource_context));
 		mutex_init(&resource_context.lock);
+		mutex_init(&resource_context.secure_lock);
 		resource_context.device = device;
 		resource_context.irq_num = irq;
 		resource_context.vidc_platform_data =
@@ -435,7 +572,7 @@
 					return;
 				}
 				resource_context.fw_mem_type =
-				resource_context.vidc_platform_data->memtype;
+				ION_MM_FIRMWARE_HEAP_ID;
 				resource_context.cmd_mem_type =
 				ION_CP_MFC_HEAP_ID;
 			}
@@ -454,12 +591,12 @@
 		}
 		resource_context.core_type = VCD_CORE_1080P;
 		resource_context.firmware_addr.mem_type = DDL_FW_MEM;
-		if (!ddl_pmem_alloc(&resource_context.firmware_addr,
+		if (!res_trk_pmem_alloc(&resource_context.firmware_addr,
 			VIDC_FW_SIZE, DDL_KILO_BYTE(128))) {
 			pr_err("%s() Firmware buffer allocation failed",
 				   __func__);
 			memset(&resource_context.firmware_addr, 0,
-				   sizeof(resource_context.firmware_addr));
+			   sizeof(resource_context.firmware_addr));
 		}
 	}
 }
@@ -470,27 +607,48 @@
 
 u32 res_trk_get_firmware_addr(struct ddl_buf_addr *firm_addr)
 {
-	int status = -1;
-	if (resource_context.firmware_addr.mapped_buffer) {
-		memcpy(firm_addr, &resource_context.firmware_addr,
-			   sizeof(struct ddl_buf_addr));
-		status = 0;
+	if (!firm_addr || resource_context.firmware_addr.mapped_buffer) {
+		pr_err("%s() invalid params", __func__);
+		return -EINVAL;
 	}
-	return status;
+	if (!res_trk_pmem_map(&resource_context.firmware_addr,
+		resource_context.firmware_addr.buffer_size,
+		DDL_KILO_BYTE(128))) {
+		pr_err("%s() Firmware buffer mapping failed",
+			   __func__);
+		return -EINVAL;
+	}
+	memcpy(firm_addr, &resource_context.firmware_addr,
+		sizeof(struct ddl_buf_addr));
+	return 0;
 }
 
-u32 res_trk_get_mem_type(void)
+int res_trk_get_mem_type(void)
 {
+	int mem_type = -1;
 	switch (resource_context.res_mem_type) {
 	case DDL_FW_MEM:
-		return resource_context.fw_mem_type;
+		mem_type = resource_context.fw_mem_type;
+		break;
 	case DDL_MM_MEM:
-		return resource_context.memtype;
+		mem_type = resource_context.memtype;
+		break;
 	case DDL_CMD_MEM:
-		return resource_context.memtype;
+		if (res_trk_check_for_sec_session())
+			mem_type = resource_context.cmd_mem_type;
+		else
+			mem_type = resource_context.memtype;
+		break;
 	default:
-		return 0;
+		return mem_type;
 	}
+	if (resource_context.vidc_platform_data->enable_ion) {
+		if (res_trk_check_for_sec_session())
+			mem_type = (ION_HEAP(mem_type) | ION_SECURE);
+		else
+			mem_type = ION_HEAP(mem_type);
+	}
+	return mem_type;
 }
 
 u32 res_trk_get_enable_ion(void)
@@ -520,3 +678,109 @@
 {
 	return resource_context.disable_fullhd;
 }
+
+int res_trk_enable_iommu_clocks(void)
+{
+	int ret = 0, i;
+	if (resource_context.mmu_clks_on) {
+		pr_err(" %s: Clocks are already on", __func__);
+		return -EINVAL;
+	}
+	resource_context.mmu_clks_on = 1;
+	for (i = 0; i < ARRAY_SIZE(vidc_mmu_clks); i++) {
+		vidc_mmu_clks[i].mmu_clk = clk_get(resource_context.device,
+			vidc_mmu_clks[i].mmu_clk_name);
+		if (IS_ERR(vidc_mmu_clks[i].mmu_clk)) {
+			pr_err(" %s: Get failed for clk %s", __func__,
+				   vidc_mmu_clks[i].mmu_clk_name);
+			ret = PTR_ERR(vidc_mmu_clks[i].mmu_clk);
+		}
+		if (!ret) {
+			ret = clk_enable(vidc_mmu_clks[i].mmu_clk);
+			if (ret) {
+				clk_put(vidc_mmu_clks[i].mmu_clk);
+				vidc_mmu_clks[i].mmu_clk = NULL;
+			}
+		}
+		if (ret) {
+			for (i--; i >= 0; i--) {
+				clk_disable(vidc_mmu_clks[i].mmu_clk);
+				clk_put(vidc_mmu_clks[i].mmu_clk);
+				vidc_mmu_clks[i].mmu_clk = NULL;
+			}
+			resource_context.mmu_clks_on = 0;
+			pr_err("%s() clocks enable failed", __func__);
+			break;
+		}
+	}
+	return ret;
+}
+
+int res_trk_disable_iommu_clocks(void)
+{
+	int i;
+	if (!resource_context.mmu_clks_on) {
+		pr_err(" %s: clks are already off", __func__);
+		return -EINVAL;
+	}
+	resource_context.mmu_clks_on = 0;
+	for (i = 0; i < ARRAY_SIZE(vidc_mmu_clks); i++) {
+		clk_disable(vidc_mmu_clks[i].mmu_clk);
+		clk_put(vidc_mmu_clks[i].mmu_clk);
+		vidc_mmu_clks[i].mmu_clk = NULL;
+	}
+	return 0;
+}
+
+int res_trk_check_for_sec_session()
+{
+	int rc;
+	mutex_lock(&resource_context.secure_lock);
+	rc = (resource_context.secure_session) ? -EBUSY : 0;
+	mutex_unlock(&resource_context.secure_lock);
+	return rc;
+}
+int res_trk_open_secure_session()
+{
+	int rc;
+	mutex_lock(&resource_context.secure_lock);
+	if (resource_context.secure_session) {
+		pr_err("Secure session already open");
+		rc = -EBUSY;
+		goto error_open;
+	}
+	resource_context.secure_session = 1;
+	rc = res_trk_enable_iommu_clocks();
+	if (rc) {
+		pr_err("IOMMU clock enabled failed while open");
+		goto error_open;
+	}
+	msm_ion_secure_heap(ION_HEAP(resource_context.memtype));
+	msm_ion_secure_heap(ION_HEAP(resource_context.cmd_mem_type));
+	res_trk_disable_iommu_clocks();
+	mutex_unlock(&resource_context.secure_lock);
+	return 0;
+error_open:
+	mutex_unlock(&resource_context.secure_lock);
+	return rc;
+}
+
+int res_trk_close_secure_session()
+{
+	int rc;
+	mutex_lock(&resource_context.secure_lock);
+	rc = res_trk_enable_iommu_clocks();
+	if (rc) {
+		pr_err("IOMMU clock enabled failed while close");
+		goto error_close;
+	}
+	msm_ion_unsecure_heap(ION_HEAP(resource_context.memtype));
+	msm_ion_unsecure_heap(ION_HEAP(resource_context.cmd_mem_type));
+	res_trk_disable_iommu_clocks();
+	resource_context.secure_session = 0;
+	mutex_unlock(&resource_context.secure_lock);
+	return 0;
+error_close:
+	mutex_unlock(&resource_context.secure_lock);
+	return rc;
+}
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h
index be5045f..bf8607d 100644
--- a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h
@@ -28,6 +28,7 @@
 
 #define RESTRK_1080P_MIN_PERF_LEVEL RESTRK_1080P_VGA_PERF_LEVEL
 #define RESTRK_1080P_MAX_PERF_LEVEL RESTRK_1080P_1080P_PERF_LEVEL
+
 struct res_trk_context {
 	struct device *device;
 	u32 irq_num;
@@ -52,6 +53,9 @@
 	u32 disable_dmx;
 	u32 disable_fullhd;
 	enum ddl_mem_area res_mem_type;
+	u32 mmu_clks_on;
+	u32 secure_session;
+	struct mutex secure_lock;
 };
 
 #if DEBUG
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h
index fd4ca3e..f91ddb5 100644
--- a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker_api.h
@@ -29,10 +29,15 @@
 u32 res_trk_download_firmware(void);
 u32 res_trk_get_core_type(void);
 u32 res_trk_get_firmware_addr(struct ddl_buf_addr *firm_addr);
-u32 res_trk_get_mem_type(void);
+int res_trk_get_mem_type(void);
 u32 res_trk_get_enable_ion(void);
 u32 res_trk_get_disable_fullhd(void);
 struct ion_client *res_trk_get_ion_client(void);
 u32 res_trk_get_disable_dmx(void);
 void res_trk_set_mem_type(enum ddl_mem_area mem_type);
+int res_trk_enable_iommu_clocks(void);
+int res_trk_disable_iommu_clocks(void);
+int res_trk_check_for_sec_session(void);
+int res_trk_open_secure_session(void);
+int res_trk_close_secure_session(void);
 #endif
diff --git a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c
index ee76ff1..7c3325a 100644
--- a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c
+++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.c
@@ -728,3 +728,18 @@
 {
 	return 0;
 }
+
+int res_trk_check_for_sec_session()
+{
+	return 0;
+}
+
+int res_trk_open_secure_session()
+{
+	return -EINVAL;
+}
+
+int res_trk_close_secure_session()
+{
+	return 0;
+}
diff --git a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h
index 3012858..2b92a42 100644
--- a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h
+++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker.h
@@ -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
@@ -35,6 +35,7 @@
 	struct msm_vidc_platform_data *vidc_platform_data;
 	u32 core_type;
 	int memtype;
+	u32 secure_session;
 };
 
 #if DEBUG
diff --git a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h
index 34f2103..237d143 100644
--- a/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h
+++ b/drivers/video/msm/vidc/720p/resource_tracker/vcd_res_tracker_api.h
@@ -32,4 +32,7 @@
 u32 res_trk_get_enable_ion(void);
 struct ion_client *res_trk_get_ion_client(void);
 void res_trk_set_mem_type(enum ddl_mem_area mem_type);
+int res_trk_check_for_sec_session(void);
+int res_trk_open_secure_session(void);
+int res_trk_close_secure_session(void);
 #endif
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
index b90248e..980ec21 100644
--- a/drivers/video/msm/vidc/common/dec/vdec.c
+++ b/drivers/video/msm/vidc/common/dec/vdec.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
@@ -29,6 +29,7 @@
 #include <linux/clk.h>
 #include <linux/timer.h>
 #include <mach/msm_subsystem_map.h>
+#include "vcd_res_tracker_api.h"
 #include "vidc_type.h"
 #include "vcd_api.h"
 #include "vdec_internal.h"
@@ -40,11 +41,13 @@
 #define INFO(x...) pr_info(x)
 #define ERR(x...) pr_err(x)
 
-#define VID_DEC_NAME		"msm_vidc_dec"
+#define VID_DEC_NAME "msm_vidc_dec"
 
+static char *node_name[2] = {"", "_sec"};
 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)
@@ -1958,34 +1961,30 @@
 	return true;
 }
 
-static int vid_dec_open(struct inode *inode, struct file *file)
+struct video_client_ctx *vid_dec_open_client(void)
 {
 	s32 client_index;
 	struct video_client_ctx *client_ctx;
 	u32 vcd_status = VCD_ERR_FAIL;
-	u8 client_count = 0;
-
-	DBG("msm_vidc_dec: Inside %s()", __func__);
-	mutex_lock(&vid_dec_device_p->lock);
+	u8 client_count;
 
 	client_count = vcd_get_num_of_clients();
 	if (client_count == VIDC_MAX_NUM_CLIENTS) {
 		ERR("ERROR : vid_dec_open() max number of clients"
-		    "limit reached\n");
-		mutex_unlock(&vid_dec_device_p->lock);
-		return -ENODEV;
+			"limit reached\n");
+		goto client_failure;
 	}
 
 	DBG(" Virtual Address of ioremap is %p\n", vid_dec_device_p->virt_base);
 	if (!vid_dec_device_p->num_clients) {
 		if (!vidc_load_firmware())
-			return -ENODEV;
+			goto client_failure;
 	}
 
 	client_index = vid_dec_get_empty_client_index();
 	if (client_index == -1) {
 		ERR("%s() : No free clients client_index == -1\n", __func__);
-		return -ENODEV;
+		goto client_failure;
 	}
 	client_ctx = &vid_dec_device_p->vdec_clients[client_index];
 	vid_dec_device_p->num_clients++;
@@ -2002,30 +2001,84 @@
 		client_ctx->user_ion_client = vcd_get_ion_client();
 		if (!client_ctx->user_ion_client) {
 			ERR("vcd_open ion client get failed");
-			return -EFAULT;
+			goto client_failure;
 		}
 	}
 	vcd_status = vcd_open(vid_dec_device_p->device_handle, true,
-			      vid_dec_vcd_cb, client_ctx);
+				  vid_dec_vcd_cb, client_ctx);
 	if (!vcd_status) {
 		wait_for_completion(&client_ctx->event);
 		if (client_ctx->event_status) {
 			ERR("callback for vcd_open returned error: %u",
 				client_ctx->event_status);
-			mutex_unlock(&vid_dec_device_p->lock);
-			return -EFAULT;
+			goto client_failure;
 		}
 	} else {
 		ERR("vcd_open returned error: %u", vcd_status);
-		mutex_unlock(&vid_dec_device_p->lock);
-		return -EFAULT;
+		goto client_failure;
 	}
 	client_ctx->seq_header_set = false;
-	file->private_data = client_ctx;
+	return client_ctx;
+client_failure:
+	return NULL;
+}
+
+static int vid_dec_open_secure(struct inode *inode, struct file *file)
+{
+	mutex_lock(&vid_dec_device_p->lock);
+	if (res_trk_check_for_sec_session() || vcd_get_num_of_clients()) {
+		ERR("Secure session present return failure\n");
+		mutex_unlock(&vid_dec_device_p->lock);
+		return -ENODEV;
+	}
+	if (res_trk_open_secure_session()) {
+		ERR("Secure session operation failure\n");
+		mutex_unlock(&vid_dec_device_p->lock);
+		return -ENODEV;
+	}
+	file->private_data = vid_dec_open_client();
+	if (!file->private_data) {
+		res_trk_close_secure_session();
+		mutex_unlock(&vid_dec_device_p->lock);
+		return -ENODEV;
+	}
 	mutex_unlock(&vid_dec_device_p->lock);
 	return 0;
 }
 
+static int vid_dec_open(struct inode *inode, struct file *file)
+{
+	INFO("msm_vidc_dec: Inside %s()", __func__);
+	mutex_lock(&vid_dec_device_p->lock);
+	if (res_trk_check_for_sec_session()) {
+		ERR("Secure session present return failure\n");
+		mutex_unlock(&vid_dec_device_p->lock);
+		return -ENODEV;
+	}
+	file->private_data = vid_dec_open_client();
+	if (!file->private_data) {
+		mutex_unlock(&vid_dec_device_p->lock);
+		return -ENODEV;
+	}
+	mutex_unlock(&vid_dec_device_p->lock);
+	return 0;
+}
+
+static int vid_dec_release_secure(struct inode *inode, struct file *file)
+{
+	struct video_client_ctx *client_ctx = file->private_data;
+
+	INFO("msm_vidc_dec: Inside %s()", __func__);
+	res_trk_close_secure_session();
+	vid_dec_close_client(client_ctx);
+	vidc_release_firmware();
+#ifndef USE_RES_TRACKER
+	vidc_disable_clk();
+#endif
+	INFO("msm_vidc_dec: Return from %s()", __func__);
+	return 0;
+}
+
 static int vid_dec_release(struct inode *inode, struct file *file)
 {
 	struct video_client_ctx *client_ctx = file->private_data;
@@ -2040,11 +2093,20 @@
 	return 0;
 }
 
-static const struct file_operations vid_dec_fops = {
-	.owner = THIS_MODULE,
-	.open = vid_dec_open,
-	.release = vid_dec_release,
-	.unlocked_ioctl = vid_dec_ioctl,
+static const struct file_operations vid_dec_fops[2] = {
+	{
+		.owner = THIS_MODULE,
+		.open = vid_dec_open,
+		.release = vid_dec_release,
+		.unlocked_ioctl = vid_dec_ioctl,
+	},
+	{
+		.owner = THIS_MODULE,
+		.open = vid_dec_open_secure,
+		.release = vid_dec_release_secure,
+		.unlocked_ioctl = vid_dec_ioctl,
+	},
+
 };
 
 void vid_dec_interrupt_deregister(void)
@@ -2110,7 +2172,7 @@
 
 static int __init vid_dec_init(void)
 {
-	int rc = 0;
+	int rc = 0, i = 0, j = 0;
 	struct device *class_devp;
 
 	DBG("msm_vidc_dec: Inside %s()", __func__);
@@ -2121,7 +2183,8 @@
 		return -ENOMEM;
 	}
 
-	rc = alloc_chrdev_region(&vid_dec_dev_num, 0, 1, VID_DEC_NAME);
+	rc = alloc_chrdev_region(&vid_dec_dev_num, 0, NUM_OF_DRIVER_NODES,
+		VID_DEC_NAME);
 	if (rc < 0) {
 		ERR("%s: alloc_chrdev_region Failed rc = %d\n",
 		       __func__, rc);
@@ -2136,49 +2199,59 @@
 
 		goto error_vid_dec_class_create;
 	}
+	for (i = 0; i < NUM_OF_DRIVER_NODES; i++) {
+		class_devp = device_create(vid_dec_class, NULL,
+						(vid_dec_dev_num + i),
+						NULL, VID_DEC_NAME "%s",
+						node_name[i]);
 
-	class_devp = device_create(vid_dec_class, NULL, vid_dec_dev_num, NULL,
-				   VID_DEC_NAME);
+		if (IS_ERR(class_devp)) {
+			rc = PTR_ERR(class_devp);
+			ERR("%s: class device_create failed %d\n",
+				   __func__, rc);
+			if (!i)
+				goto error_vid_dec_class_device_create;
+			else
+				goto error_vid_dec_cdev_add;
+		}
 
-	if (IS_ERR(class_devp)) {
-		rc = PTR_ERR(class_devp);
-		ERR("%s: class device_create failed %d\n",
-		       __func__, rc);
-		goto error_vid_dec_class_device_create;
-	}
+	  vid_dec_device_p->device[i] = class_devp;
 
-  vid_dec_device_p->device = class_devp;
+		cdev_init(&vid_dec_device_p->cdev[i], &vid_dec_fops[i]);
+		vid_dec_device_p->cdev[i].owner = THIS_MODULE;
+		rc = cdev_add(&(vid_dec_device_p->cdev[i]),
+				(vid_dec_dev_num+i), 1);
 
-	cdev_init(&vid_dec_device_p->cdev, &vid_dec_fops);
-	vid_dec_device_p->cdev.owner = THIS_MODULE;
-	rc = cdev_add(&(vid_dec_device_p->cdev), vid_dec_dev_num, 1);
-
-	if (rc < 0) {
-		ERR("%s: cdev_add failed %d\n", __func__, rc);
-		goto error_vid_dec_cdev_add;
+		if (rc < 0) {
+			ERR("%s: cdev_add failed %d\n", __func__, rc);
+			goto error_vid_dec_cdev_add;
+		}
 	}
 	vid_dec_vcd_init();
 	return 0;
 
 error_vid_dec_cdev_add:
+	for (j = i-1; j >= 0; j--)
+		cdev_del(&(vid_dec_device_p->cdev[j]));
 	device_destroy(vid_dec_class, vid_dec_dev_num);
 error_vid_dec_class_device_create:
 	class_destroy(vid_dec_class);
 error_vid_dec_class_create:
-	unregister_chrdev_region(vid_dec_dev_num, 1);
+	unregister_chrdev_region(vid_dec_dev_num, NUM_OF_DRIVER_NODES);
 error_vid_dec_alloc_chrdev_region:
 	kfree(vid_dec_device_p);
-
 	return rc;
 }
 
 static void __exit vid_dec_exit(void)
 {
-	DBG("msm_vidc_dec: Inside %s()", __func__);
-	cdev_del(&(vid_dec_device_p->cdev));
+	int i = 0;
+	INFO("msm_vidc_dec: Inside %s()", __func__);
+	for (i = 0; i < NUM_OF_DRIVER_NODES; i++)
+		cdev_del(&(vid_dec_device_p->cdev[i]));
 	device_destroy(vid_dec_class, vid_dec_dev_num);
 	class_destroy(vid_dec_class);
-	unregister_chrdev_region(vid_dec_dev_num, 1);
+	unregister_chrdev_region(vid_dec_dev_num, NUM_OF_DRIVER_NODES);
 	kfree(vid_dec_device_p);
 	DBG("msm_vidc_dec: Return from %s()", __func__);
 }
diff --git a/drivers/video/msm/vidc/common/dec/vdec_internal.h b/drivers/video/msm/vidc/common/dec/vdec_internal.h
index 867c3b3..f310e25 100644
--- a/drivers/video/msm/vidc/common/dec/vdec_internal.h
+++ b/drivers/video/msm/vidc/common/dec/vdec_internal.h
@@ -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
@@ -18,14 +18,16 @@
 #include <linux/cdev.h>
 #include "vidc_init.h"
 
+#define NUM_OF_DRIVER_NODES 2
+
 struct vid_dec_msg {
 	struct list_head list;
 	struct vdec_msginfo vdec_msg_info;
 };
 
 struct vid_dec_dev {
-	struct cdev cdev;
-	struct device *device;
+	struct cdev cdev[NUM_OF_DRIVER_NODES];
+	struct device *device[NUM_OF_DRIVER_NODES];
 	resource_size_t phys_base;
 	void __iomem *virt_base;
 	unsigned int irq;
diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
index 3cd4e76..97fc758 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-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
@@ -32,6 +32,7 @@
 #include "vcd_api.h"
 #include "venc_internal.h"
 #include "vidc_init.h"
+#include "vcd_res_tracker_api.h"
 
 #define VID_ENC_NAME	"msm_vidc_enc"
 
@@ -516,9 +517,10 @@
 
 	stop_cmd = 0;
 	client_count = vcd_get_num_of_clients();
-	if (client_count == VIDC_MAX_NUM_CLIENTS) {
+	if (client_count == VIDC_MAX_NUM_CLIENTS ||
+		res_trk_check_for_sec_session()) {
 		ERR("ERROR : vid_enc_open() max number of clients"
-		    "limit reached\n");
+		    "limit reached or secure session is open\n");
 		mutex_unlock(&vid_enc_device_p->lock);
 		return -ENODEV;
 	}
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.c b/drivers/video/msm/vidc/common/init/vidc_init.c
index e4bd50d..1709cc2 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init.c
+++ b/drivers/video/msm/vidc/common/init/vidc_init.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
@@ -502,7 +502,7 @@
 		} else {
 			buff_ion_handle = ion_import_fd(
 				client_ctx->user_ion_client, pmem_fd);
-			if (!buff_ion_handle) {
+			if (IS_ERR_OR_NULL(buff_ion_handle)) {
 				ERR("%s(): get_ION_handle failed\n",
 				 __func__);
 				goto ion_error;
@@ -558,7 +558,7 @@
 ion_error:
 	if (*kernel_vaddr)
 		ion_unmap_kernel(client_ctx->user_ion_client, buff_ion_handle);
-	if (buff_ion_handle)
+	if (!IS_ERR_OR_NULL(buff_ion_handle))
 		ion_free(client_ctx->user_ion_client, buff_ion_handle);
 bail_out_add:
 	mutex_unlock(&client_ctx->enrty_queue_lock);
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_api.c b/drivers/video/msm/vidc/common/vcd/vcd_api.c
index 4889761..5e9fd55 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_api.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_api.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
@@ -89,7 +89,10 @@
 
 		return VCD_ERR_ILLEGAL_PARM;
 	}
-
+	if (res_trk_check_for_sec_session() && vcd_get_num_of_clients()) {
+		VCD_MSG_ERROR("Secure session in progress");
+		return VCD_ERR_BAD_STATE;
+	}
 	drv_ctxt = vcd_get_drv_context();
 	mutex_lock(&drv_ctxt->dev_mutex);
 
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_sub.c b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
index bb3e652..b5fcc1c 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_sub.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
@@ -69,7 +69,7 @@
 	} else {
 		map_buffer->alloc_handle = ion_alloc(
 			    cctxt->vcd_ion_client, sz, SZ_4K,
-			    (1<<memtype));
+			    memtype);
 		if (!map_buffer->alloc_handle) {
 			pr_err("%s() ION alloc failed", __func__);
 			goto bailout;
diff --git a/include/linux/i2c/atmel_mxt_ts.h b/include/linux/i2c/atmel_mxt_ts.h
index d61b934..9aa557a 100644
--- a/include/linux/i2c/atmel_mxt_ts.h
+++ b/include/linux/i2c/atmel_mxt_ts.h
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2010 Samsung Electronics Co.Ltd
  * Author: Joonyoung Shim <jy0922.shim@samsung.com>
- * 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 as published by the
@@ -26,6 +26,9 @@
 #define MXT_ROTATED_180		0x6
 #define MXT_DIAGONAL_COUNTER	0x7
 
+/* MXT_TOUCH_KEYARRAY_T15 */
+#define MXT_KEYARRAY_MAX_KEYS	32
+
 /* The platform data for the Atmel maXTouch touchscreen driver */
 struct mxt_platform_data {
 	const u8 *config;
@@ -38,6 +41,7 @@
 	bool	digital_pwr_regulator;
 	int reset_gpio;
 	int irq_gpio;
+	int *key_codes;
 
 	u8(*read_chg) (void);
 	int (*init_hw) (bool);
diff --git a/include/linux/ion.h b/include/linux/ion.h
index fa5017a..41f99e4 100644
--- a/include/linux/ion.h
+++ b/include/linux/ion.h
@@ -63,14 +63,17 @@
  */
 
 enum ion_heap_ids {
+	INVALID_HEAP_ID = -1,
 	ION_IOMMU_HEAP_ID = 4,
 	ION_CP_MM_HEAP_ID = 8,
 	ION_CP_MFC_HEAP_ID = 12,
 	ION_CP_WB_HEAP_ID = 16, /* 8660 only */
 	ION_CAMERA_HEAP_ID = 20, /* 8660 only */
 	ION_SF_HEAP_ID = 24,
+	ION_QSECOM_HEAP_ID = 27,
 	ION_AUDIO_HEAP_ID = 28,
 
+	ION_MM_FIRMWARE_HEAP_ID = 29,
 	ION_SYSTEM_HEAP_ID = 30,
 
 	ION_HEAP_ID_RESERVED = 31 /** Bit reserved for ION_SECURE flag */
@@ -94,6 +97,8 @@
 #define ION_IOMMU_HEAP_NAME	"iommu"
 #define ION_MFC_HEAP_NAME	"mfc"
 #define ION_WB_HEAP_NAME	"wb"
+#define ION_MM_FIRMWARE_HEAP_NAME	"mm_fw"
+#define ION_QSECOM_HEAP_NAME	"qsecom"
 
 #define CACHED          1
 #define UNCACHED        0
@@ -149,12 +154,17 @@
 
 struct ion_cp_heap_pdata {
 	enum ion_permission_type permission_type;
+	unsigned int align;
+	ion_phys_addr_t secure_base; /* Base addr used when heap is shared */
+	size_t secure_size; /* Size used for securing heap when heap is shared*/
 	int (*request_region)(void *);
 	int (*release_region)(void *);
 	void *(*setup_region)(void);
 };
 
 struct ion_co_heap_pdata {
+	int adjacent_mem_id;
+	unsigned int align;
 	int (*request_region)(void *);
 	int (*release_region)(void *);
 	void *(*setup_region)(void);
diff --git a/include/linux/mfd/pm8xxx/pm8038.h b/include/linux/mfd/pm8xxx/pm8038.h
index e733842..203095a 100644
--- a/include/linux/mfd/pm8xxx/pm8038.h
+++ b/include/linux/mfd/pm8xxx/pm8038.h
@@ -1,5 +1,5 @@
 /*
- * 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
@@ -28,6 +28,9 @@
 #include <linux/mfd/pm8xxx/misc.h>
 #include <linux/regulator/pm8xxx-regulator.h>
 #include <linux/mfd/pm8xxx/pm8xxx-adc.h>
+#include <linux/mfd/pm8xxx/pm8921-charger.h>
+#include <linux/mfd/pm8xxx/pm8921-bms.h>
+#include <linux/mfd/pm8xxx/ccadc.h>
 
 #define PM8038_CORE_DEV_NAME "pm8038-core"
 
@@ -69,7 +72,10 @@
 	struct pm8xxx_misc_platform_data	*misc_pdata;
 	struct pm8xxx_regulator_platform_data	*regulator_pdatas;
 	int					num_regulators;
+	struct pm8921_charger_platform_data	*charger_pdata;
+	struct pm8921_bms_platform_data		*bms_pdata;
 	struct pm8xxx_adc_platform_data		*adc_pdata;
+	struct pm8xxx_ccadc_platform_data	*ccadc_pdata;
 };
 
 #endif
diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
index cd2e61c..d0307ee 100644
--- a/include/linux/of_irq.h
+++ b/include/linux/of_irq.h
@@ -33,6 +33,8 @@
 	u32 specifier[OF_MAX_IRQ_SPEC]; /* Specifier copy */
 };
 
+typedef int (*of_irq_init_cb_t)(struct device_node *, struct device_node *);
+
 /*
  * Workarounds only applied to 32bit powermac machines
  */
@@ -73,6 +75,7 @@
 		struct resource *res, int nr_irqs);
 extern struct device_node *of_irq_find_parent(struct device_node *child);
 
+extern void of_irq_init(const struct of_device_id *matches);
 
 #endif /* CONFIG_OF_IRQ */
 #endif /* CONFIG_OF */
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
index fb5d4e4..f46449a 100644
--- a/include/linux/regulator/consumer.h
+++ b/include/linux/regulator/consumer.h
@@ -135,6 +135,8 @@
 /* regulator get and put */
 struct regulator *__must_check regulator_get(struct device *dev,
 					     const char *id);
+struct regulator *__must_check devm_regulator_get(struct device *dev,
+					     const char *id);
 struct regulator *__must_check regulator_get_exclusive(struct device *dev,
 						       const char *id);
 void regulator_put(struct regulator *regulator);
@@ -202,6 +204,13 @@
 	 */
 	return NULL;
 }
+
+static inline struct regulator *__must_check
+devm_regulator_get(struct device *dev, const char *id)
+{
+	return NULL;
+}
+
 static inline void regulator_put(struct regulator *regulator)
 {
 }
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index 472fcae..30da5c6 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -41,6 +41,8 @@
 #define TABLA_TX_DAI_ID 2
 #define TABLA_CFILT_FAST_MODE 0x00
 #define TABLA_CFILT_SLOW_MODE 0x40
+#define MBHC_FW_READ_ATTEMPTS 15
+#define MBHC_FW_READ_TIMEOUT 2000000
 
 #define TABLA_JACK_MASK (SND_JACK_HEADSET | SND_JACK_OC_HPHL | SND_JACK_OC_HPHR)
 
@@ -186,6 +188,10 @@
 
 	/* Callback function to enable MCLK */
 	int (*mclk_cb) (struct snd_soc_codec*, int);
+
+	/* Work to perform MBHC Firmware Read */
+	struct delayed_work mbhc_firmware_dwork;
+	const struct firmware *mbhc_fw;
 };
 
 #ifdef CONFIG_DEBUG_FS
@@ -3592,6 +3598,91 @@
 	snd_soc_update_bits(codec, TABLA_A_CDC_MBHC_B1_CTL, 0x02, 0x02);
 }
 
+static bool tabla_mbhc_fw_validate(const struct firmware *fw)
+{
+	u32 cfg_offset;
+	struct tabla_mbhc_imped_detect_cfg *imped_cfg;
+	struct tabla_mbhc_btn_detect_cfg *btn_cfg;
+
+	if (fw->size < TABLA_MBHC_CAL_MIN_SIZE)
+		return false;
+
+	/* previous check guarantees that there is enough fw data up
+	 * to num_btn
+	 */
+	btn_cfg = TABLA_MBHC_CAL_BTN_DET_PTR(fw->data);
+	cfg_offset = (u32) ((void *) btn_cfg - (void *) fw->data);
+	if (fw->size < (cfg_offset + TABLA_MBHC_CAL_BTN_SZ(btn_cfg)))
+		return false;
+
+	/* previous check guarantees that there is enough fw data up
+	 * to start of impedance detection configuration
+	 */
+	imped_cfg = TABLA_MBHC_CAL_IMPED_DET_PTR(fw->data);
+	cfg_offset = (u32) ((void *) imped_cfg - (void *) fw->data);
+
+	if (fw->size < (cfg_offset + TABLA_MBHC_CAL_IMPED_MIN_SZ))
+		return false;
+
+	if (fw->size < (cfg_offset + TABLA_MBHC_CAL_IMPED_SZ(imped_cfg)))
+		return false;
+
+	return true;
+}
+static void mbhc_fw_read(struct work_struct *work)
+{
+	struct delayed_work *dwork;
+	struct tabla_priv *tabla;
+	struct snd_soc_codec *codec;
+	const struct firmware *fw;
+	int ret = -1, retry = 0, rc;
+
+	dwork = to_delayed_work(work);
+	tabla = container_of(dwork, struct tabla_priv,
+				mbhc_firmware_dwork);
+	codec = tabla->codec;
+
+	while (retry < MBHC_FW_READ_ATTEMPTS) {
+		retry++;
+		pr_info("%s:Attempt %d to request MBHC firmware\n",
+			__func__, retry);
+		ret = request_firmware(&fw, "wcd9310/wcd9310_mbhc.bin",
+					codec->dev);
+
+		if (ret != 0) {
+			usleep_range(MBHC_FW_READ_TIMEOUT,
+					MBHC_FW_READ_TIMEOUT);
+		} else {
+			pr_info("%s: MBHC Firmware read succesful\n", __func__);
+			break;
+		}
+	}
+
+	if (ret != 0) {
+		pr_err("%s: Cannot load MBHC firmware use default cal\n",
+			__func__);
+	} else if (tabla_mbhc_fw_validate(fw) == false) {
+		pr_err("%s: Invalid MBHC cal data size use default cal\n",
+			 __func__);
+		release_firmware(fw);
+	} else {
+		tabla->calibration = (void *)fw->data;
+		tabla->mbhc_fw = fw;
+	}
+
+	tabla->mclk_cb(codec, 1);
+	tabla_mbhc_init(codec);
+	tabla_mbhc_cal(codec);
+	tabla_mbhc_calc_thres(codec);
+	tabla->mclk_cb(codec, 0);
+	tabla_codec_calibrate_hs_polling(codec);
+	rc = tabla_codec_enable_hs_detect(codec, 1);
+
+	if (IS_ERR_VALUE(rc))
+		pr_err("%s: Failed to setup MBHC detection\n", __func__);
+
+}
+
 int tabla_hs_detect(struct snd_soc_codec *codec,
 		    struct snd_soc_jack *headset_jack,
 		    struct snd_soc_jack *button_jack,
@@ -3600,7 +3691,7 @@
 		    int read_fw_bin, u32 mclk_rate)
 {
 	struct tabla_priv *tabla;
-	int rc;
+	int rc = 0;
 
 	if (!codec || !calibration) {
 		pr_err("Error: no codec or calibration\n");
@@ -3618,7 +3709,7 @@
 	/* Put CFILT in fast mode by default */
 	snd_soc_update_bits(codec, tabla->mbhc_bias_regs.cfilt_ctl,
 		0x40, TABLA_CFILT_FAST_MODE);
-
+	INIT_DELAYED_WORK(&tabla->mbhc_firmware_dwork, mbhc_fw_read);
 	INIT_DELAYED_WORK(&tabla->btn0_dwork, btn0_lpress_fn);
 	INIT_WORK(&tabla->hphlocp_work, hphlocp_off_report);
 	INIT_WORK(&tabla->hphrocp_work, hphrocp_off_report);
@@ -3632,8 +3723,8 @@
 		tabla_codec_calibrate_hs_polling(codec);
 		rc =  tabla_codec_enable_hs_detect(codec, 1);
 	} else {
-		pr_err("%s: MBHC firmware read not supported\n", __func__);
-		rc = -EINVAL;
+		schedule_delayed_work(&tabla->mbhc_firmware_dwork,
+				usecs_to_jiffies(MBHC_FW_READ_TIMEOUT));
 	}
 
 	if (!IS_ERR_VALUE(rc)) {
@@ -4552,6 +4643,8 @@
 	tabla_free_irq(codec->control_data, TABLA_IRQ_MBHC_INSERTION, tabla);
 	tabla_codec_disable_clock_block(codec);
 	tabla_codec_enable_bandgap(codec, TABLA_BANDGAP_OFF);
+	if (tabla->mbhc_fw)
+		release_firmware(tabla->mbhc_fw);
 	kfree(tabla);
 	return 0;
 }
diff --git a/sound/soc/codecs/wcd9310.h b/sound/soc/codecs/wcd9310.h
index 66c3e39..3f987cc 100644
--- a/sound/soc/codecs/wcd9310.h
+++ b/sound/soc/codecs/wcd9310.h
@@ -197,3 +197,29 @@
 	       sizeof(TABLA_MBHC_CAL_BTN_DET_PTR(cali)->_v_btn_high[0])))) \
 	)
 
+/* minimum size of calibration data assuming there is only one button and
+ * one rload.
+ */
+#define TABLA_MBHC_CAL_MIN_SIZE ( \
+	sizeof(struct tabla_mbhc_general_cfg) + \
+	sizeof(struct tabla_mbhc_plug_detect_cfg) + \
+	sizeof(struct tabla_mbhc_plug_type_cfg) + \
+	sizeof(struct tabla_mbhc_btn_detect_cfg) + \
+	sizeof(struct tabla_mbhc_imped_detect_cfg) + \
+	(sizeof(u16) * 2))
+
+#define TABLA_MBHC_CAL_BTN_SZ(cfg_ptr) ( \
+	    sizeof(struct tabla_mbhc_btn_detect_cfg) + \
+	    (cfg_ptr->num_btn * (sizeof(cfg_ptr->_v_btn_low[0]) + \
+				 sizeof(cfg_ptr->_v_btn_high[0]))))
+
+#define TABLA_MBHC_CAL_IMPED_MIN_SZ ( \
+	    sizeof(struct tabla_mbhc_imped_detect_cfg) + \
+	    sizeof(u16) * 2)
+
+#define TABLA_MBHC_CAL_IMPED_SZ(cfg_ptr) ( \
+	    sizeof(struct tabla_mbhc_imped_detect_cfg) + \
+	    (cfg_ptr->_n_rload * (sizeof(cfg_ptr->_rload[0]) + \
+				 sizeof(cfg_ptr->_alpha[0]))))
+
+
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
index 590d4af..d0497b1 100644
--- a/sound/soc/msm/msm-compr-q6.c
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -47,10 +47,10 @@
 	.channels_min =	 1,
 	.channels_max =	 2,
 	.buffer_bytes_max =     1200 * 1024 * 2,
-	.period_bytes_min =	60 * 1024,
+	.period_bytes_min =	4800,
 	.period_bytes_max =     1200 * 1024,
 	.periods_min =	  2,
-	.periods_max =	  40,
+	.periods_max =	  512,
 	.fifo_size =	    0,
 };
 
diff --git a/sound/soc/msm/qdsp6/q6afe.c b/sound/soc/msm/qdsp6/q6afe.c
index 21bbcf2..74a66945 100644
--- a/sound/soc/msm/qdsp6/q6afe.c
+++ b/sound/soc/msm/qdsp6/q6afe.c
@@ -56,6 +56,7 @@
 		pr_debug("task_name = %s pid = %d\n",
 			this_afe.task->comm, this_afe.task->pid);
 		send_sig(SIGUSR1, this_afe.task, 0);
+		return 0;
 	}
 	if (data->payload_size) {
 		uint32_t *payload;
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index ab7f9f7..62168d2 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -515,6 +515,7 @@
 						pr_err("%s:map_buffer failed,"
 							"error = %ld\n",
 				__func__, PTR_ERR((void *)buf[cnt].mem_buffer));
+						mutex_unlock(&ac->cmd_lock);
 						goto fail;
 					}
 					buf[cnt].data =
@@ -522,6 +523,7 @@
 					if (!buf[cnt].data) {
 						pr_err("%s:invalid vaddr,"
 						" iomap failed\n", __func__);
+						mutex_unlock(&ac->cmd_lock);
 						goto fail;
 					}
 					buf[cnt].used = 1;
@@ -944,6 +946,7 @@
 		idx = port->cpu_buf;
 		if (port->buf == NULL) {
 			pr_debug("%s:Buffer pointer null\n", __func__);
+			mutex_unlock(&port->lock);
 			return NULL;
 		}
 		/*  dir 0: used = 0 means buf in use