Merge "regulator: Add devm_regulator_get()" 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/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/common/gic.c b/arch/arm/common/gic.c
index a6b5d0b..0455878 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -788,7 +788,7 @@
 {
 	struct gic_chip_data *gic;
 	struct irq_domain *domain;
-	int gic_irqs;
+	int gic_irqs, rc;
 
 	BUG_ON(gic_nr >= MAX_GIC_NR);
 
@@ -801,11 +801,8 @@
 		gic->dist_base.percpu_base = alloc_percpu(void __iomem *);
 		gic->cpu_base.percpu_base = alloc_percpu(void __iomem *);
 		if (WARN_ON(!gic->dist_base.percpu_base ||
-			    !gic->cpu_base.percpu_base)) {
-			free_percpu(gic->dist_base.percpu_base);
-			free_percpu(gic->cpu_base.percpu_base);
-			return;
-		}
+			    !gic->cpu_base.percpu_base))
+			goto init_bases_err;
 
 		for_each_possible_cpu(cpu) {
 			unsigned long offset = percpu_offset * cpu_logical_map(cpu);
@@ -857,12 +854,23 @@
 	}
 	domain->priv = gic;
 	domain->ops = &gic_irq_domain_ops;
-	irq_domain_add(domain);
+	rc = irq_domain_add(domain);
+	if (rc) {
+		WARN(1, "Unable to create irq_domain\n");
+		goto init_bases_err;
+	}
+	irq_domain_register(domain);
 
 	gic_chip.flags |= gic_arch_extn.flags;
 	gic_dist_init(gic);
 	gic_cpu_init(gic);
 	gic_pm_init(gic);
+
+	return;
+
+init_bases_err:
+	free_percpu(gic->dist_base.percpu_base);
+	free_percpu(gic->cpu_base.percpu_base);
 }
 
 void __cpuinit gic_secondary_init(unsigned int gic_nr)
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/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index d8d2e35..0780d20 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -257,6 +257,7 @@
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_UINPUT=y
 CONFIG_INPUT_PMIC8XXX_PWRKEY=y
+# CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_MSM=y
 CONFIG_SERIAL_MSM_HS=y
 # CONFIG_SERIAL_MSM_CLOCK_CONTROL is not set
@@ -320,6 +321,7 @@
 CONFIG_FB_MSM_OVERLAY0_WRITEBACK=y
 CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
 CONFIG_FB_MSM_HDMI_MSM_PANEL=y
+CONFIG_FB_MSM_WRITEBACK_MSM_PANEL=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 CONFIG_SOUND=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 5e90492..bd92fe3 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -260,6 +260,7 @@
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_UINPUT=y
 CONFIG_INPUT_PMIC8XXX_PWRKEY=y
+# CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_MSM=y
 CONFIG_SERIAL_MSM_HS=y
 # CONFIG_SERIAL_MSM_CLOCK_CONTROL is not set
@@ -323,6 +324,7 @@
 CONFIG_FB_MSM_OVERLAY0_WRITEBACK=y
 CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
 CONFIG_FB_MSM_HDMI_MSM_PANEL=y
+CONFIG_FB_MSM_WRITEBACK_MSM_PANEL=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 CONFIG_SOUND=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 9f66e5d..0ba7434 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -22,6 +22,7 @@
 #include <linux/spi/spi.h>
 #include <linux/dma-mapping.h>
 #include <linux/platform_data/qcom_crypto_device.h>
+#include <linux/ion.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/hardware/gic.h>
@@ -29,6 +30,7 @@
 
 #include <mach/board.h>
 #include <mach/msm_iomap.h>
+#include <mach/ion.h>
 #include <linux/usb/msm_hsusb.h>
 #include <linux/usb/android.h>
 #include <mach/socinfo.h>
@@ -37,36 +39,48 @@
 #include "devices.h"
 #include <mach/gpio.h>
 #include <mach/gpiomux.h>
+#ifdef CONFIG_ANDROID_PMEM
 #include <linux/android_pmem.h>
+#endif
 #include <mach/msm_memtypes.h>
 #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"
 
-#define MSM_PMEM_KERNEL_EBI1_SIZE  0x600000
-#define MSM_PMEM_ADSP_SIZE         0x3800000
+#define MSM_PMEM_ADSP_SIZE         0x7800000
 #define MSM_PMEM_AUDIO_SIZE        0x2B4000
-#define MSM_PMEM_SIZE 0x1800000 /* 24 Mbytes */
+#ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
+#define MSM_PMEM_SIZE 0x4000000 /* 64 Mbytes */
+#else
+#define MSM_PMEM_SIZE 0x2800000 /* 40 Mbytes */
+#endif
 
-static struct memtype_reserve apq8064_reserve_table[] __initdata = {
-	[MEMTYPE_SMI] = {
-	},
-	[MEMTYPE_EBI0] = {
-		.flags	=	MEMTYPE_FLAGS_1M_ALIGN,
-	},
-	[MEMTYPE_EBI1] = {
-		.flags	=	MEMTYPE_FLAGS_1M_ALIGN,
-	},
-};
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+#define MSM_PMEM_KERNEL_EBI1_SIZE  0xB0C000
+#define MSM_ION_SF_SIZE		MSM_PMEM_SIZE
+#define MSM_ION_MM_SIZE		MSM_PMEM_ADSP_SIZE
+#define MSM_ION_MFC_SIZE	SZ_8K
+#define MSM_ION_HEAP_NUM	5
+#else
+#define MSM_PMEM_KERNEL_EBI1_SIZE  0x110C000
+#define MSM_ION_HEAP_NUM	1
+#endif
 
-static int apq8064_paddr_to_memtype(unsigned int paddr)
+#ifdef CONFIG_KERNEL_PMEM_EBI_REGION
+static unsigned pmem_kernel_ebi1_size = MSM_PMEM_KERNEL_EBI1_SIZE;
+static int __init pmem_kernel_ebi1_size_setup(char *p)
 {
-	return MEMTYPE_EBI1;
+	pmem_kernel_ebi1_size = memparse(p, NULL);
+	return 0;
 }
+early_param("pmem_kernel_ebi1_size", pmem_kernel_ebi1_size_setup);
+#endif
 
+#ifdef CONFIG_ANDROID_PMEM
 static unsigned pmem_size = MSM_PMEM_SIZE;
 static int __init pmem_size_setup(char *p)
 {
@@ -92,7 +106,10 @@
 	return 0;
 }
 early_param("pmem_audio_size", pmem_audio_size_setup);
+#endif
 
+#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 static struct android_pmem_platform_data android_pmem_pdata = {
 	.name = "pmem",
 	.allocator_type = PMEM_ALLOCATORTYPE_ALLORNOTHING,
@@ -112,20 +129,12 @@
 	.cached = 0,
 	.memory_type = MEMTYPE_EBI1,
 };
-
-static unsigned pmem_kernel_ebi1_size = MSM_PMEM_KERNEL_EBI1_SIZE;
-static int __init pmem_kernel_ebi1_size_setup(char *p)
-{
-	pmem_kernel_ebi1_size = memparse(p, NULL);
-	return 0;
-}
-early_param("pmem_kernel_ebi1_size", pmem_kernel_ebi1_size_setup);
-
 static struct platform_device android_pmem_adsp_device = {
 	.name = "android_pmem",
 	.id = 2,
 	.dev = { .platform_data = &android_pmem_adsp_pdata },
 };
+#endif
 
 static struct android_pmem_platform_data android_pmem_audio_pdata = {
 	.name = "pmem_audio",
@@ -139,12 +148,28 @@
 	.id = 4,
 	.dev = { .platform_data = &android_pmem_audio_pdata },
 };
+#endif
+
+static struct memtype_reserve apq8064_reserve_table[] __initdata = {
+	[MEMTYPE_SMI] = {
+	},
+	[MEMTYPE_EBI0] = {
+		.flags	=	MEMTYPE_FLAGS_1M_ALIGN,
+	},
+	[MEMTYPE_EBI1] = {
+		.flags	=	MEMTYPE_FLAGS_1M_ALIGN,
+	},
+};
 
 static void __init size_pmem_devices(void)
 {
+#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 	android_pmem_adsp_pdata.size = pmem_adsp_size;
 	android_pmem_pdata.size = pmem_size;
+#endif
 	android_pmem_audio_pdata.size = MSM_PMEM_AUDIO_SIZE;
+#endif
 }
 
 static void __init reserve_memory_for(struct android_pmem_platform_data *p)
@@ -154,16 +179,97 @@
 
 static void __init reserve_pmem_memory(void)
 {
+#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 	reserve_memory_for(&android_pmem_adsp_pdata);
 	reserve_memory_for(&android_pmem_pdata);
+#endif
 	reserve_memory_for(&android_pmem_audio_pdata);
 	apq8064_reserve_table[MEMTYPE_EBI1].size += pmem_kernel_ebi1_size;
+#endif
+}
+
+static int apq8064_paddr_to_memtype(unsigned int paddr)
+{
+	return MEMTYPE_EBI1;
+}
+
+#ifdef CONFIG_ION_MSM
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+static struct ion_cp_heap_pdata cp_mm_ion_pdata = {
+	.permission_type = IPT_TYPE_MM_CARVEOUT,
+};
+
+static struct ion_cp_heap_pdata cp_mfc_ion_pdata = {
+	.permission_type = IPT_TYPE_MFC_SHAREDMEM,
+};
+
+static struct ion_co_heap_pdata co_ion_pdata = {
+};
+#endif
+static struct ion_platform_data ion_pdata = {
+	.nr = MSM_ION_HEAP_NUM,
+	.heaps = {
+		{
+			.id	= ION_SYSTEM_HEAP_ID,
+			.type	= ION_HEAP_TYPE_SYSTEM,
+			.name	= ION_VMALLOC_HEAP_NAME,
+		},
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+		{
+			.id	= ION_SF_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_SF_HEAP_NAME,
+			.size	= MSM_ION_SF_SIZE,
+			.memory_type = ION_EBI_TYPE,
+			.extra_data = (void *) &co_ion_pdata,
+		},
+		{
+			.id	= ION_CP_MM_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CP,
+			.name	= ION_MM_HEAP_NAME,
+			.size	= MSM_ION_MM_SIZE,
+			.memory_type = ION_EBI_TYPE,
+			.extra_data = (void *) &cp_mm_ion_pdata,
+		},
+		{
+			.id	= ION_CP_MFC_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CP,
+			.name	= ION_MFC_HEAP_NAME,
+			.size	= MSM_ION_MFC_SIZE,
+			.memory_type = ION_EBI_TYPE,
+			.extra_data = (void *) &cp_mfc_ion_pdata,
+		},
+		{
+			.id	= ION_IOMMU_HEAP_ID,
+			.type	= ION_HEAP_TYPE_IOMMU,
+			.name	= ION_IOMMU_HEAP_NAME,
+		},
+#endif
+	}
+};
+
+static struct platform_device ion_dev = {
+	.name = "ion-msm",
+	.id = 1,
+	.dev = { .platform_data = &ion_pdata },
+};
+#endif
+
+static void reserve_ion_memory(void)
+{
+#if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
+	apq8064_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MM_SIZE;
+	apq8064_reserve_table[MEMTYPE_EBI1].size += MSM_ION_SF_SIZE;
+	apq8064_reserve_table[MEMTYPE_EBI1].size += MSM_ION_MFC_SIZE;
+#endif
 }
 
 static void __init apq8064_calculate_reserve_sizes(void)
 {
 	size_pmem_devices();
 	reserve_pmem_memory();
+	reserve_ion_memory();
 }
 
 static struct reserve_info apq8064_reserve_info __initdata = {
@@ -453,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,
@@ -464,9 +586,16 @@
 	&apq8064_device_otg,
 	&apq8064_device_gadget_peripheral,
 	&android_usb_device,
+#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 	&android_pmem_device,
 	&android_pmem_adsp_device,
+#endif
 	&android_pmem_audio_device,
+#endif
+#ifdef CONFIG_ION_MSM
+	&ion_dev,
+#endif
 	&msm8064_device_watchdog,
 	&msm8064_device_saw_regulator_core0,
 	&msm8064_device_saw_regulator_core1,
@@ -507,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 = {
@@ -600,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 91bee0b..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
 }
 
@@ -1491,6 +1529,12 @@
 	.msm_apps_ipc_rpm_val = 4,
 };
 
+static struct msm_pm_sleep_status_data msm_pm_slp_sts_data = {
+	.base_addr = MSM_ACC0_BASE + 0x08,
+	.cpu_offset = MSM_ACC1_BASE - MSM_ACC0_BASE,
+	.mask = 1UL << 13,
+};
+
 static struct ks8851_pdata spi_eth_pdata = {
 	.irq_gpio = KS8851_IRQ_GPIO,
 	.rst_gpio = KS8851_RST_GPIO,
@@ -2167,6 +2211,7 @@
 	msm_cpuidle_set_states(msm_cstates, ARRAY_SIZE(msm_cstates),
 				msm_pm_data);
 	BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
+	msm_pm_init_sleep_status_data(&msm_pm_slp_sts_data);
 }
 
 static void __init msm8960_rumi3_init(void)
@@ -2198,6 +2243,7 @@
 	msm_cpuidle_set_states(msm_cstates, ARRAY_SIZE(msm_cstates),
 				msm_pm_data);
 	BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
+	msm_pm_init_sleep_status_data(&msm_pm_slp_sts_data);
 }
 
 static void __init msm8960_cdp_init(void)
@@ -2273,6 +2319,7 @@
 				msm_pm_data);
 	change_memory_power = &msm8960_change_memory_power;
 	BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
+	msm_pm_init_sleep_status_data(&msm_pm_slp_sts_data);
 	if (PLATFORM_IS_CHARM25())
 		platform_add_devices(mdm_devices, ARRAY_SIZE(mdm_devices));
 }
diff --git a/arch/arm/mach-msm/board-9615-regulator.c b/arch/arm/mach-msm/board-9615-regulator.c
index 4859f18..95a1347 100644
--- a/arch/arm/mach-msm/board-9615-regulator.c
+++ b/arch/arm/mach-msm/board-9615-regulator.c
@@ -69,6 +69,7 @@
 VREG_CONSUMERS(S1) = {
 	REGULATOR_SUPPLY("8018_s1",		NULL),
 	REGULATOR_SUPPLY("HSUSB_VDDCX",		"msm_otg"),
+	REGULATOR_SUPPLY("HSIC_VDDCX",		"msm_hsic_peripheral"),
 };
 VREG_CONSUMERS(S2) = {
 	REGULATOR_SUPPLY("8018_s2",		NULL),
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index 37e4606..f708b11 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -385,6 +385,7 @@
 	&msm_device_charger,
 #endif
 	&msm_device_otg,
+	&msm_device_hsic_peripheral,
 	&msm_device_gadget_peripheral,
 	&msm_device_hsusb_host,
 	&msm_device_usb_bam,
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-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 404c5d4..5bcd749 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -154,7 +154,7 @@
 #define MSM_PMEM_MDP_SIZE       0x2300000
 #define MSM7x25A_MSM_PMEM_MDP_SIZE       0x1500000
 
-#define MSM_PMEM_ADSP_SIZE      0x1000000
+#define MSM_PMEM_ADSP_SIZE      0x1100000
 #define MSM7x25A_MSM_PMEM_ADSP_SIZE      0xB91000
 
 
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-9615.c b/arch/arm/mach-msm/devices-9615.c
index 0c46c9d..314d064 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.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
@@ -170,6 +170,29 @@
 	},
 };
 
+static struct resource resources_hsic_peripheral[] = {
+	{
+		.start	= MSM9615_HSIC_PHYS,
+		.end	= MSM9615_HSIC_PHYS + MSM9615_HSIC_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= USB_HSIC_IRQ,
+		.end	= USB_HSIC_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device msm_device_hsic_peripheral = {
+	.name		= "msm_hsic_peripheral",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(resources_hsic_peripheral),
+	.resource	= resources_hsic_peripheral,
+	.dev		= {
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+};
+
 static struct resource resources_hsusb_host[] = {
 	{
 		.start  = MSM9615_HSUSB_PHYS,
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 6d8d393..5d28fa9 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -94,7 +94,7 @@
 extern struct platform_device msm_device_hsic_host;
 
 extern struct platform_device msm_device_otg;
-
+extern struct platform_device msm_device_hsic_peripheral;
 extern struct platform_device msm8960_device_otg;
 extern struct platform_device msm8960_device_gadget_peripheral;
 
@@ -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/irqs-9615.h b/arch/arm/mach-msm/include/mach/irqs-9615.h
index 74e5847..5fba24e 100644
--- a/arch/arm/mach-msm/include/mach/irqs-9615.h
+++ b/arch/arm/mach-msm/include/mach/irqs-9615.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -179,8 +179,9 @@
 #define TLMM_MSM_DIR_CONN_IRQ_21		(GIC_SPI_START + 224)
 #define MSM_SPARE0_IRQ				(GIC_SPI_START + 225)
 #define PMIC_SEC_IRQ_N				(GIC_SPI_START + 226)
+#define USB_HSIC_IRQ				(GIC_SPI_START + 232)
 
-#define NR_MSM_IRQS 256
+#define NR_MSM_IRQS 288
 #define NR_GPIO_IRQS 88
 #define NR_PM8018_IRQS 256
 #define NR_BOARD_IRQS NR_PM8018_IRQS
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-9615.h b/arch/arm/mach-msm/include/mach/msm_iomap-9615.h
index dda5f50..fc9b198 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-9615.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-9615.h
@@ -1,6 +1,6 @@
 /*
  * 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
@@ -77,6 +77,9 @@
 #define MSM9615_HSUSB_PHYS		0x12500000
 #define MSM9615_HSUSB_SIZE		SZ_4K
 
+#define MSM9615_HSIC_PHYS		0x12540000
+#define MSM9615_HSIC_SIZE		SZ_4K
+
 #define MSM9615_QFPROM_PHYS		0x00700000
 #define MSM9615_QFPROM_SIZE		SZ_4K
 
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/include/mach/pm.h b/arch/arm/mach-msm/include/mach/pm.h
index 813ece1..689cd17 100644
--- a/arch/arm/mach-msm/include/mach/pm.h
+++ b/arch/arm/mach-msm/include/mach/pm.h
@@ -51,11 +51,19 @@
 				staying in the low power mode saves power */
 };
 
+struct msm_pm_sleep_status_data {
+	void *base_addr;
+	uint32_t cpu_offset;
+	uint32_t mask;
+};
+
 void msm_pm_set_platform_data(struct msm_pm_platform_data *data, int count);
 int msm_pm_idle_prepare(struct cpuidle_device *dev);
 int msm_pm_idle_enter(enum msm_pm_sleep_mode sleep_mode);
 void msm_pm_cpu_enter_lowpower(unsigned int cpu);
 
+void __init msm_pm_init_sleep_status_data(
+		struct msm_pm_sleep_status_data *sleep_data);
 #ifdef CONFIG_PM
 void msm_pm_set_rpm_wakeup_irq(unsigned int irq);
 #else
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/msm_dsps.c b/arch/arm/mach-msm/msm_dsps.c
index 4e487a7..efb2bf6 100644
--- a/arch/arm/mach-msm/msm_dsps.c
+++ b/arch/arm/mach-msm/msm_dsps.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -39,8 +39,10 @@
 #include <mach/subsystem_restart.h>
 #include <mach/subsystem_notif.h>
 
+#include <timer.h>
+
 #define DRV_NAME	"msm_dsps"
-#define DRV_VERSION	"3.01"
+#define DRV_VERSION	"3.02"
 
 #define PPSS_PAUSE_REG	0x1804
 
@@ -146,9 +148,9 @@
 {
 	u32 val;
 
-	val = readl_relaxed(drv->ppss_base + PPSS_TIMER0_32KHZ_REG);
-	rmb(); /* order reads from the user output buffer */
-
+	/* Read the timer value from the MSM sclk. The MSM slow clock & DSPS
+	 * timers are in sync, so these are the same value */
+	val = msm_timer_get_sclk_ticks();
 	pr_debug("%s.count=%d.\n", __func__, val);
 
 	return val;
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/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index a6644d6..754d76f 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -27,6 +27,7 @@
 #include <linux/tick.h>
 #include <linux/uaccess.h>
 #include <linux/wakelock.h>
+#include <linux/delay.h>
 #include <mach/msm_iomap.h>
 #include <mach/system.h>
 #include <asm/cacheflush.h>
@@ -55,6 +56,7 @@
  * Debug Definitions
  *****************************************************************************/
 
+
 enum {
 	MSM_PM_DEBUG_SUSPEND = BIT(0),
 	MSM_PM_DEBUG_POWER_COLLAPSE = BIT(1),
@@ -953,6 +955,23 @@
 	return 0;
 }
 
+static struct msm_pm_sleep_status_data *msm_pm_slp_sts;
+
+static DEFINE_PER_CPU_SHARED_ALIGNED(enum msm_pm_sleep_mode,
+		msm_pm_last_slp_mode);
+
+bool msm_pm_verify_cpu_pc(unsigned int cpu)
+{
+	enum msm_pm_sleep_mode mode = per_cpu(msm_pm_last_slp_mode, cpu);
+
+	if (msm_pm_slp_sts)
+		if ((mode == MSM_PM_SLEEP_MODE_POWER_COLLAPSE) ||
+			(mode == MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE))
+			return true;
+
+	return false;
+}
+
 void msm_pm_cpu_enter_lowpower(unsigned int cpu)
 {
 	int i;
@@ -968,14 +987,50 @@
 	if (MSM_PM_DEBUG_HOTPLUG & msm_pm_debug_mask)
 		pr_notice("CPU%u: %s: shutting down cpu\n", cpu, __func__);
 
-	if (allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE])
+	if (allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE]) {
+		per_cpu(msm_pm_last_slp_mode, cpu)
+			= MSM_PM_SLEEP_MODE_POWER_COLLAPSE;
 		msm_pm_power_collapse(false);
-	else if (allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE])
+	} else if (allow[MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE]) {
+		per_cpu(msm_pm_last_slp_mode, cpu)
+			= MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE;
 		msm_pm_power_collapse_standalone(false);
-	else if (allow[MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT])
+	} else if (allow[MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT]) {
+		per_cpu(msm_pm_last_slp_mode, cpu)
+			= MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE;
 		msm_pm_swfi();
+	} else
+		per_cpu(msm_pm_last_slp_mode, cpu) = MSM_PM_SLEEP_MODE_NR;
+}
 
+int msm_pm_wait_cpu_shutdown(unsigned int cpu)
+{
 
+	int timeout = 10;
+
+	if (!msm_pm_slp_sts)
+		return 0;
+
+	while (timeout--) {
+
+		/*
+		 * Check for the SPM of the core being hotplugged to set
+		 * its sleep state.The SPM sleep state indicates that the
+		 * core has been power collapsed.
+		 */
+
+		int acc_sts = __raw_readl(msm_pm_slp_sts->base_addr
+					+ cpu * msm_pm_slp_sts->cpu_offset);
+		mb();
+
+		if (acc_sts & msm_pm_slp_sts->mask)
+			return 0;
+
+		usleep(100);
+	}
+	pr_warn("%s(): Timed out waiting for CPU %u SPM to enter sleep state",
+			__func__, cpu);
+	return -EBUSY;
 }
 
 static int msm_pm_enter(suspend_state_t state)
@@ -1085,10 +1140,14 @@
 	.valid = suspend_valid_only_mem,
 };
 
-
 /******************************************************************************
  * Initialization routine
  *****************************************************************************/
+void __init msm_pm_init_sleep_status_data(
+		struct msm_pm_sleep_status_data *data)
+{
+	msm_pm_slp_sts = data;
+}
 
 static int __init msm_pm_init(void)
 {
diff --git a/arch/arm/mach-msm/scm-pas.c b/arch/arm/mach-msm/scm-pas.c
index 0a9b27c..747b585 100644
--- a/arch/arm/mach-msm/scm-pas.c
+++ b/arch/arm/mach-msm/scm-pas.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
@@ -94,7 +94,7 @@
 {
 	int ret = 0;
 
-	if (!scm_perf_client || scm_bus_clk)
+	if (!scm_perf_client || !scm_bus_clk)
 		return -EINVAL;
 
 	mutex_lock(&scm_pas_bw_mutex);
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-msm/timer.c b/arch/arm/mach-msm/timer.c
index 61e65d2..67b1f7b 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -405,11 +405,7 @@
  */
 static void (*msm_timer_sync_timeout)(void);
 #if defined(CONFIG_MSM_DIRECT_SCLK_ACCESS)
-static uint32_t msm_timer_do_sync_to_sclk(
-	void (*time_start)(struct msm_timer_sync_data_t *data),
-	bool (*time_expired)(struct msm_timer_sync_data_t *data),
-	void (*update)(struct msm_timer_sync_data_t *, uint32_t, uint32_t),
-	struct msm_timer_sync_data_t *data)
+uint32_t msm_timer_get_sclk_ticks(void)
 {
 	uint32_t t1, t2;
 	int loop_count = 10;
@@ -442,7 +438,18 @@
 		return 0;
 	}
 
-	if (update != NULL)
+	return t1;
+}
+
+static uint32_t msm_timer_do_sync_to_sclk(
+	void (*time_start)(struct msm_timer_sync_data_t *data),
+	bool (*time_expired)(struct msm_timer_sync_data_t *data),
+	void (*update)(struct msm_timer_sync_data_t *, uint32_t, uint32_t),
+	struct msm_timer_sync_data_t *data)
+{
+	unsigned t1 = msm_timer_get_sclk_ticks();
+
+	if (t1 && update != NULL)
 		update(data, t1, sclk_hz);
 	return t1;
 }
diff --git a/arch/arm/mach-msm/timer.h b/arch/arm/mach-msm/timer.h
index 545675c..caef19d 100644
--- a/arch/arm/mach-msm/timer.h
+++ b/arch/arm/mach-msm/timer.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 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
@@ -20,5 +20,6 @@
 int64_t msm_timer_enter_idle(void);
 void msm_timer_exit_idle(int low_power);
 int64_t msm_timer_get_sclk_time(int64_t *period);
+uint32_t msm_timer_get_sclk_ticks(void);
 int msm_timer_init_time_sync(void (*timeout)(void));
 #endif
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 7e72391..5ed2ad7 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-12, 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
@@ -2034,10 +2034,8 @@
 
 	iris_q_event(radio, IRIS_EVT_NEW_RT_RDS);
 
-	while (skb->data[len+RDS_OFFSET] != 0x0d)
+	while ((skb->data[len+RDS_OFFSET] != 0x0d) && (len < RX_RT_DATA_LENGTH))
 		len++;
-	len++;
-
 	data = kmalloc(len+RDS_OFFSET, GFP_ATOMIC);
 	if (!data) {
 		FMDERR("Failed to allocate memory");
@@ -2088,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);
@@ -3255,7 +3254,7 @@
 		if ((i == IRIS_BUF_RAW_RDS) || (i == IRIS_BUF_PEEK))
 			kfifo_alloc_rc = kfifo_alloc(&radio->data_buf[i],
 				rds_buf*3, GFP_KERNEL);
-		else if (i == IRIS_BUF_CAL_DATA)
+		else if ((i == IRIS_BUF_CAL_DATA) || (i == IRIS_BUF_RT_RDS))
 			kfifo_alloc_rc = kfifo_alloc(&radio->data_buf[i],
 				STD_BUF_SIZE*2, GFP_KERNEL);
 		else
diff --git a/drivers/media/radio/radio-tavarua.c b/drivers/media/radio/radio-tavarua.c
index 393e30e..8f09b6a 100644
--- a/drivers/media/radio/radio-tavarua.c
+++ b/drivers/media/radio/radio-tavarua.c
@@ -2107,7 +2107,7 @@
 			 1, internal_vreg_ctl[index][0]);
 		if (retval < 0) {
 			printk(KERN_ERR "%s:0xF0 write failed\n", __func__);
-			return retval;
+			goto exit;
 		}
 		/* actual value itself used as mask*/
 		retval = marimba_write_bit_mask(radio->marimba,
@@ -2115,7 +2115,7 @@
 			1, internal_vreg_ctl[index][1]);
 		if (retval < 0) {
 			printk(KERN_ERR "%s:0xF4 write failed\n", __func__);
-			return retval;
+			goto exit;
 		}
 	} else    {
 		/* disable fm core */
@@ -2127,8 +2127,9 @@
 							&value, 1, FM_ENABLE);
 	if (retval < 0) {
 		printk(KERN_ERR "%s:XO_BUFF_CNTRL write failed\n", __func__);
-		return retval;
+		goto exit;
 	}
+exit:
 	FMDBG("%s, Calling fm_shutdown\n", __func__);
 	/* teardown gpio and pmic */
 
@@ -2139,7 +2140,7 @@
 	radio->handle_irq = 1;
 	atomic_inc(&radio->users);
 	radio->marimba->mod_id = SLAVE_ID_BAHAMA;
-	return 0;
+	return retval;
 }
 
 /*
@@ -2864,6 +2865,7 @@
 	unsigned char value;
 	unsigned char xfr_buf[XFR_REG_NUM];
 	unsigned char tx_data[XFR_REG_NUM];
+	unsigned char dis_buf[XFR_REG_NUM];
 
 	switch (ctrl->id) {
 	case V4L2_CID_AUDIO_VOLUME:
@@ -2915,20 +2917,26 @@
 		/* check if off */
 		else if ((ctrl->value == FM_OFF) && radio->registers[RDCTRL]) {
 			FMDBG("turning off...\n");
-			retval = tavarua_write_register(radio, RDCTRL,
-							ctrl->value);
-			/*Make it synchronous
-			Block it till READY interrupt
-			Wait for interrupt i.e.
-			complete(&radio->sync_req_done)
-			*/
+			tavarua_write_register(radio, RDCTRL, ctrl->value);
+			/* flush the event and work queues */
+			kfifo_reset(&radio->data_buf[TAVARUA_BUF_EVENTS]);
+			flush_workqueue(radio->wqueue);
+			/*
+			 * queue the READY event from the host side
+			 * in case of FM off
+			 */
+			tavarua_q_event(radio, TAVARUA_EVT_RADIO_READY);
 
-			if (retval >= 0) {
-
-				if (!wait_for_completion_timeout(
-					&radio->sync_req_done,
-					msecs_to_jiffies(wait_timeout)))
-					FMDBG("turning off timedout...\n");
+			FMDBG("%s, Disable All Interrupts\n", __func__);
+			/* disable irq */
+			dis_buf[STATUS_REG1] = 0x00;
+			dis_buf[STATUS_REG2] = 0x00;
+			dis_buf[STATUS_REG3] = TRANSFER;
+			retval = sync_write_xfr(radio, INT_CTRL, dis_buf);
+			if (retval < 0) {
+				pr_err("%s: failed to disable"
+						"Interrupts\n", __func__);
+				return retval;
 			}
 		}
 		break;
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index 8df6243..363e437 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.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
@@ -674,14 +674,12 @@
 static int msm_camera_v4l2_querycap(struct file *f, void *pctx,
 				struct v4l2_capability *pcaps)
 {
-	struct msm_cam_v4l2_device *pcam  = video_drvdata(f);
 
 	D("%s\n", __func__);
 	WARN_ON(pctx != f->private_data);
 
 	/* some other day, some other time */
 	/*cap->version = LINUX_VERSION_CODE; */
-	strlcpy(pcaps->driver, pcam->pdev->name, sizeof(pcaps->driver));
 	pcaps->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
 	return 0;
 }
diff --git a/drivers/media/video/msm/msm_camera.c b/drivers/media/video/msm/msm_camera.c
index e401a7a..65b33c2 100644
--- a/drivers/media/video/msm/msm_camera.c
+++ b/drivers/media/video/msm/msm_camera.c
@@ -1010,7 +1010,7 @@
 		qcmd_resp = __msm_control_nb(sync, qcmd);
 		goto end;
 	}
-
+	msm_queue_drain(&ctrl_pmsm->ctrl_q, list_control);
 	qcmd_resp = __msm_control(sync,
 				  &ctrl_pmsm->ctrl_q,
 				  qcmd, msecs_to_jiffies(10000));
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index 759ac47..e13dd62 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.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
@@ -76,6 +76,22 @@
 	.colorspace = V4L2_COLORSPACE_JPEG,
 	},
 	{
+	.name	   = "NV16BAYER",
+	.depth	  = 8,
+	.bitsperpxl = 8,
+	.fourcc	 = V4L2_PIX_FMT_NV16,
+	.pxlcode	= V4L2_MBUS_FMT_SBGGR10_1X10, /* Bayer sensor */
+	.colorspace = V4L2_COLORSPACE_JPEG,
+	},
+	{
+	.name	   = "NV61BAYER",
+	.depth	  = 8,
+	.bitsperpxl = 8,
+	.fourcc	 = V4L2_PIX_FMT_NV61,
+	.pxlcode	= V4L2_MBUS_FMT_SBGGR10_1X10, /* Bayer sensor */
+	.colorspace = V4L2_COLORSPACE_JPEG,
+	},
+	{
 	.name	   = "YU12BAYER",
 	.depth	  = 8,
 	.bitsperpxl = 8,
diff --git a/drivers/media/video/videobuf2-msm-mem.c b/drivers/media/video/videobuf2-msm-mem.c
index fa7e3fd..37b935b 100644
--- a/drivers/media/video/videobuf2-msm-mem.c
+++ b/drivers/media/video/videobuf2-msm-mem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * Based on videobuf-dma-contig.c,
  * (c) 2008 Magnus Damm
@@ -45,17 +45,51 @@
 #define D(fmt, args...) do {} while (0)
 #endif
 
-static int32_t msm_mem_allocate(const size_t size)
+static int32_t msm_mem_allocate(struct videobuf2_contig_pmem *mem)
 {
 	int32_t phyaddr;
-	phyaddr = allocate_contiguous_ebi_nomap(size, SZ_4K);
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	int rc, len;
+	mem->client = msm_ion_client_create(-1, "camera");
+	if (IS_ERR((void *)mem->client)) {
+		pr_err("%s Could not create client\n", __func__);
+		goto client_failed;
+	}
+	mem->ion_handle = ion_alloc(mem->client, mem->size, SZ_4K,
+		(0x1 << ION_CP_MM_HEAP_ID | 0x1 << ION_IOMMU_HEAP_ID));
+	if (IS_ERR((void *)mem->ion_handle)) {
+		pr_err("%s Could not allocate\n", __func__);
+		goto alloc_failed;
+	}
+	rc = ion_phys(mem->client, mem->ion_handle, (ion_phys_addr_t *)&phyaddr,
+		 (size_t *)&len);
+	if (rc < 0) {
+		pr_err("%s Could not get physical address\n", __func__);
+		goto phys_failed;
+	}
+#else
+	phyaddr = allocate_contiguous_ebi_nomap(mem->size, SZ_4K);
+#endif
 	return phyaddr;
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+phys_failed:
+	ion_free(mem->client, mem->ion_handle);
+alloc_failed:
+	ion_client_destroy(mem->client);
+client_failed:
+	return 0;
+#endif
 }
 
-static int32_t msm_mem_free(const int32_t phyaddr)
+static int32_t msm_mem_free(struct videobuf2_contig_pmem *mem)
 {
 	int32_t rc = 0;
-	free_contiguous_memory_by_paddr(phyaddr);
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	ion_free(mem->client, mem->ion_handle);
+	ion_client_destroy(mem->client);
+#else
+	free_contiguous_memory_by_paddr(mem->phyaddr);
+#endif
 	return rc;
 }
 
@@ -92,7 +126,7 @@
 	mem->size =  PAGE_ALIGN(size);
 	mem->alloc_ctx = alloc_ctx;
 	mem->is_userptr = 0;
-	mem->phyaddr = msm_mem_allocate(mem->size);
+	mem->phyaddr = msm_mem_allocate(mem);
 	if (!mem->phyaddr) {
 		pr_err("%s : pmem memory allocation failed\n", __func__);
 		kfree(mem);
@@ -105,7 +139,7 @@
 	if (IS_ERR((void *)mem->msm_buffer)) {
 		pr_err("%s: msm_subsystem_map_buffer failed\n", __func__);
 		rc = PTR_ERR((void *)mem->msm_buffer);
-		msm_mem_free(mem->phyaddr);
+		msm_mem_free(mem);
 		kfree(mem);
 		return ERR_PTR(-ENOMEM);
 	}
@@ -119,7 +153,7 @@
 		D("%s Freeing memory ", __func__);
 		if (msm_subsystem_unmap_buffer(mem->msm_buffer) < 0)
 			D("%s unmapped memory\n", __func__);
-		msm_mem_free(mem->phyaddr);
+		msm_mem_free(mem);
 	}
 	kfree(mem);
 }
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/misc/tzcom.c b/drivers/misc/tzcom.c
index ba03064..e662f43 100644
--- a/drivers/misc/tzcom.c
+++ b/drivers/misc/tzcom.c
@@ -1,6 +1,6 @@
 /* Qualcomm TrustZone communicator driver
  *
- * 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,7 @@
 #include <linux/mutex.h>
 #include <linux/android_pmem.h>
 #include <linux/io.h>
+#include <linux/ion.h>
 #include <mach/scm.h>
 #include <mach/peripheral-loader.h>
 #include <linux/tzcom.h>
@@ -53,7 +54,7 @@
 static struct class *driver_class;
 static dev_t tzcom_device_no;
 static struct cdev tzcom_cdev;
-
+struct ion_client *ion_clnt;
 static u8 *sb_in_virt;
 static s32 sb_in_phys;
 static size_t sb_in_length = 20 * SZ_1K;
@@ -280,13 +281,13 @@
  *      _________________________________________________________
  *                              OUTPUT SHARED BUFFER
  */
-static int tzcom_send_cmd(struct tzcom_data_t *data, void __user *argp)
+static int __tzcom_send_cmd(struct tzcom_data_t *data,
+			struct tzcom_send_cmd_op_req *req)
 {
 	int ret = 0;
 	unsigned long flags;
 	u32 reqd_len_sb_in = 0;
 	u32 reqd_len_sb_out = 0;
-	struct tzcom_send_cmd_op_req req;
 	struct tzcom_command cmd;
 	struct tzcom_response resp;
 	struct tzcom_callback *next_callback;
@@ -296,30 +297,24 @@
 	size_t new_entry_len = 0;
 	struct tzcom_registered_svc_list *ptr_svc;
 
-	ret = copy_from_user(&req, argp, sizeof(req));
-	if (ret) {
-		PERR("copy_from_user failed");
-		return ret;
-	}
-
-	if (req.cmd_buf == NULL || req.resp_buf == NULL) {
+	if (req->cmd_buf == NULL || req->resp_buf == NULL) {
 		PERR("cmd buffer or response buffer is null");
 		return -EINVAL;
 	}
 
-	if (req.cmd_len <= 0 || req.resp_len <= 0 ||
-		req.cmd_len > sb_in_length || req.resp_len > sb_in_length) {
+	if (req->cmd_len <= 0 || req->resp_len <= 0 ||
+		req->cmd_len > sb_in_length || req->resp_len > sb_in_length) {
 		PERR("cmd buffer length or "
 				"response buffer length not valid");
 		return -EINVAL;
 	}
 	PDEBUG("received cmd_req.req: 0x%p",
-				req.cmd_buf);
+				req->cmd_buf);
 	PDEBUG("received cmd_req.rsp size: %u, ptr: 0x%p",
-			req.resp_len,
-			req.resp_buf);
+			req->resp_len,
+			req->resp_buf);
 
-	reqd_len_sb_in = req.cmd_len + req.resp_len;
+	reqd_len_sb_in = req->cmd_len + req->resp_len;
 	if (reqd_len_sb_in > sb_in_length) {
 		PDEBUG("Not enough memory to fit cmd_buf and "
 				"resp_buf. Required: %u, Available: %u",
@@ -327,23 +322,25 @@
 		return -ENOMEM;
 	}
 
-	/* Copy req.cmd_buf to SB in and set req.resp_buf to SB in + cmd_len */
+	/* Copy req->cmd_buf to SB in and set
+	 * req->resp_buf to SB in + cmd_len
+	 */
 	mutex_lock(&sb_in_lock);
 	PDEBUG("Before memcpy on sb_in");
-	memcpy(sb_in_virt, req.cmd_buf, req.cmd_len);
+	memcpy(sb_in_virt, req->cmd_buf, req->cmd_len);
 	PDEBUG("After memcpy on sb_in");
 
 	/* cmd_type will always be a new here */
 	cmd.cmd_type = TZ_SCHED_CMD_NEW;
 	cmd.sb_in_cmd_addr = (u8 *) tzcom_virt_to_phys(sb_in_virt);
-	cmd.sb_in_cmd_len = req.cmd_len;
+	cmd.sb_in_cmd_len = req->cmd_len;
 
 	resp.cmd_status = TZ_SCHED_STATUS_INCOMPLETE;
 	resp.sb_in_rsp_addr = (u8 *) tzcom_virt_to_phys(sb_in_virt +
-			req.cmd_len);
-	resp.sb_in_rsp_len = req.resp_len;
+			req->cmd_len);
+	resp.sb_in_rsp_len = req->resp_len;
 
-	PDEBUG("before call tzcom_scm_call, cmd_id = : %u", req.cmd_id);
+	PDEBUG("before call tzcom_scm_call, cmd_id = : %u", req->cmd_id);
 	PDEBUG("before call tzcom_scm_call, sizeof(cmd) = : %u", sizeof(cmd));
 
 	ret = tzcom_scm_call((const void *) &cmd, sizeof(cmd),
@@ -442,13 +439,31 @@
 
 	mutex_lock(&sb_in_lock);
 	resp.sb_in_rsp_addr = sb_in_virt + cmd.sb_in_cmd_len;
-	resp.sb_in_rsp_len = req.resp_len;
-	memcpy(req.resp_buf, resp.sb_in_rsp_addr, resp.sb_in_rsp_len);
+	resp.sb_in_rsp_len = req->resp_len;
+	memcpy(req->resp_buf, resp.sb_in_rsp_addr, resp.sb_in_rsp_len);
 	/* Zero out memory for security purpose */
 	memset(sb_in_virt, 0, reqd_len_sb_in);
 	mutex_unlock(&sb_in_lock);
 
-	PDEBUG("sending cmd_req.rsp "
+	return ret;
+}
+
+
+static int tzcom_send_cmd(struct tzcom_data_t *data, void __user *argp)
+{
+	int ret = 0;
+	struct tzcom_send_cmd_op_req req;
+
+	ret = copy_from_user(&req, argp, sizeof(req));
+	if (ret) {
+		PERR("copy_from_user failed");
+		return ret;
+	}
+	ret = __tzcom_send_cmd(data, &req);
+	if (ret)
+		return ret;
+
+	PDEBUG("sending cmd_req->rsp "
 			"size: %u, ptr: 0x%p", req.resp_len,
 			req.resp_buf);
 	ret = copy_to_user(argp, &req, sizeof(req));
@@ -456,7 +471,99 @@
 		PDEBUG("copy_to_user failed");
 		return ret;
 	}
+	return ret;
+}
 
+static int __tzcom_send_cmd_req_clean_up(
+			struct tzcom_send_cmd_fd_op_req *req)
+{
+	char *field;
+	uint32_t *update;
+	int ret = 0;
+	int i = 0;
+
+	for (i = 0; i < MAX_ION_FD; i++) {
+		if (req->ifd_data[i].fd != 0) {
+			field = (char *)req->cmd_buf +
+					req->ifd_data[i].cmd_buf_offset;
+			update = (uint32_t *) field;
+			*update = 0;
+		}
+	}
+	return ret;
+}
+
+static int __tzcom_update_with_phy_addr(
+			struct tzcom_send_cmd_fd_op_req *req)
+{
+	struct ion_handle *ihandle;
+	char *field;
+	uint32_t *update;
+	ion_phys_addr_t pa;
+	int ret = 0;
+	int i = 0;
+	uint32_t length;
+
+	for (i = 0; i < MAX_ION_FD; i++) {
+		if (req->ifd_data[i].fd != 0) {
+			/* Get the handle of the shared fd */
+			ihandle = ion_import_fd(ion_clnt, req->ifd_data[i].fd);
+			if (ihandle == NULL) {
+				PERR("Ion client can't retrieve the handle\n");
+				return -ENOMEM;
+			}
+			field = (char *) req->cmd_buf +
+						req->ifd_data[i].cmd_buf_offset;
+			update = (uint32_t *) field;
+
+			/* Populate the cmd data structure with the phys_addr */
+			ret = ion_phys(ion_clnt, ihandle, &pa, &length);
+			if (ret)
+				return -ENOMEM;
+
+			*update = (uint32_t)pa;
+			ion_free(ion_clnt, ihandle);
+		}
+	}
+	return ret;
+}
+
+static int tzcom_send_cmd_with_fd(struct tzcom_data_t *data,
+					void __user *argp)
+{
+	int ret = 0;
+	struct tzcom_send_cmd_fd_op_req req;
+	struct tzcom_send_cmd_op_req send_cmd_req;
+
+	ret = copy_from_user(&req, argp, sizeof(req));
+	if (ret) {
+		PERR("copy_from_user failed");
+		return ret;
+	}
+
+	send_cmd_req.cmd_id = req.cmd_id;
+	send_cmd_req.cmd_buf = req.cmd_buf;
+	send_cmd_req.cmd_len = req.cmd_len;
+	send_cmd_req.resp_buf = req.resp_buf;
+	send_cmd_req.resp_len = req.resp_len;
+
+	ret = __tzcom_update_with_phy_addr(&req);
+	if (ret)
+		return ret;
+	ret = __tzcom_send_cmd(data, &send_cmd_req);
+	__tzcom_send_cmd_req_clean_up(&req);
+
+	if (ret)
+		return ret;
+
+	PDEBUG("sending cmd_req->rsp "
+			"size: %u, ptr: 0x%p", req.resp_len,
+			req.resp_buf);
+	ret = copy_to_user(argp, &req, sizeof(req));
+	if (ret) {
+		PDEBUG("copy_to_user failed");
+		return ret;
+	}
 	return ret;
 }
 
@@ -713,6 +820,19 @@
 			PERR("failed tzcom_send_cmd: %d", ret);
 		break;
 	}
+	case TZCOM_IOCTL_SEND_CMD_FD_REQ: {
+		PDEBUG("ioctl send_cmd_req()");
+		/* Only one client allowed here at a time */
+		mutex_lock(&send_cmd_lock);
+		atomic_inc(&tzcom_data->ioctl_count);
+		ret = tzcom_send_cmd_with_fd(tzcom_data, argp);
+		atomic_dec(&tzcom_data->ioctl_count);
+		wake_up_interruptible(&tzcom_data->abort_wq);
+		mutex_unlock(&send_cmd_lock);
+		if (ret)
+			PERR("failed tzcom_send_cmd: %d", ret);
+		break;
+	}
 	case TZCOM_IOCTL_READ_NEXT_CMD_REQ: {
 		PDEBUG("ioctl read_next_cmd_req()");
 		atomic_inc(&tzcom_data->ioctl_count);
@@ -971,7 +1091,7 @@
 	}
 	PDEBUG("sb_out virt address: %p, phys address: 0x%x",
 			sb_out_virt, tzcom_virt_to_phys(sb_out_virt));
-
+	ion_clnt = msm_ion_client_create(0x03, "tzcom");
 	/* Initialized in tzcom_open */
 	pil = NULL;
 
@@ -1012,6 +1132,7 @@
 	device_destroy(driver_class, tzcom_device_no);
 	class_destroy(driver_class);
 	unregister_chrdev_region(tzcom_device_no, 1);
+	ion_client_destroy(ion_clnt);
 }
 
 
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/spi/spi_qsd.c b/drivers/spi/spi_qsd.c
index aaeb790..17b9f0d 100644
--- a/drivers/spi/spi_qsd.c
+++ b/drivers/spi/spi_qsd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-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
@@ -38,608 +38,49 @@
 #include <linux/gpio.h>
 #include <linux/remote_spinlock.h>
 #include <linux/pm_qos_params.h>
+#include <linux/of.h>
+#include "spi_qsd.h"
 
-#define SPI_DRV_NAME                  "spi_qsd"
-#if defined(CONFIG_SPI_QSD) || defined(CONFIG_SPI_QSD_MODULE)
-
-#define QSD_REG(x) (x)
-#define QUP_REG(x)
-
-#define SPI_FIFO_WORD_CNT             0x0048
-
-#elif defined(CONFIG_SPI_QUP) || defined(CONFIG_SPI_QUP_MODULE)
-
-#define QSD_REG(x)
-#define QUP_REG(x) (x)
-
-#define QUP_CONFIG                    0x0000 /* N & NO_INPUT/NO_OUPUT bits */
-#define QUP_ERROR_FLAGS               0x0308
-#define QUP_ERROR_FLAGS_EN            0x030C
-#define QUP_ERR_MASK                  0x3
-#define SPI_OUTPUT_FIFO_WORD_CNT      0x010C
-#define SPI_INPUT_FIFO_WORD_CNT       0x0214
-#define QUP_MX_WRITE_COUNT            0x0150
-#define QUP_MX_WRITE_CNT_CURRENT      0x0154
-
-#define QUP_CONFIG_SPI_MODE           0x0100
-
-#define GSBI_CTRL_REG                 0x0
-#define GSBI_SPI_CONFIG               0x30
-#endif
-
-#define SPI_CONFIG                    QSD_REG(0x0000) QUP_REG(0x0300)
-#define SPI_IO_CONTROL                QSD_REG(0x0004) QUP_REG(0x0304)
-#define SPI_IO_MODES                  QSD_REG(0x0008) QUP_REG(0x0008)
-#define SPI_SW_RESET                  QSD_REG(0x000C) QUP_REG(0x000C)
-#define SPI_TIME_OUT                  QSD_REG(0x0010) QUP_REG(0x0010)
-#define SPI_TIME_OUT_CURRENT          QSD_REG(0x0014) QUP_REG(0x0014)
-#define SPI_MX_OUTPUT_COUNT           QSD_REG(0x0018) QUP_REG(0x0100)
-#define SPI_MX_OUTPUT_CNT_CURRENT     QSD_REG(0x001C) QUP_REG(0x0104)
-#define SPI_MX_INPUT_COUNT            QSD_REG(0x0020) QUP_REG(0x0200)
-#define SPI_MX_INPUT_CNT_CURRENT      QSD_REG(0x0024) QUP_REG(0x0204)
-#define SPI_MX_READ_COUNT             QSD_REG(0x0028) QUP_REG(0x0208)
-#define SPI_MX_READ_CNT_CURRENT       QSD_REG(0x002C) QUP_REG(0x020C)
-#define SPI_OPERATIONAL               QSD_REG(0x0030) QUP_REG(0x0018)
-#define SPI_ERROR_FLAGS               QSD_REG(0x0034) QUP_REG(0x001C)
-#define SPI_ERROR_FLAGS_EN            QSD_REG(0x0038) QUP_REG(0x0020)
-#define SPI_DEASSERT_WAIT             QSD_REG(0x003C) QUP_REG(0x0310)
-#define SPI_OUTPUT_DEBUG              QSD_REG(0x0040) QUP_REG(0x0108)
-#define SPI_INPUT_DEBUG               QSD_REG(0x0044) QUP_REG(0x0210)
-#define SPI_TEST_CTRL                 QSD_REG(0x004C) QUP_REG(0x0024)
-#define SPI_OUTPUT_FIFO               QSD_REG(0x0100) QUP_REG(0x0110)
-#define SPI_INPUT_FIFO                QSD_REG(0x0200) QUP_REG(0x0218)
-#define SPI_STATE                     QSD_REG(SPI_OPERATIONAL) QUP_REG(0x0004)
-
-/* SPI_CONFIG fields */
-#define SPI_CFG_INPUT_FIRST           0x00000200
-#define SPI_NO_INPUT                  0x00000080
-#define SPI_NO_OUTPUT                 0x00000040
-#define SPI_CFG_LOOPBACK              0x00000100
-#define SPI_CFG_N                     0x0000001F
-
-/* SPI_IO_CONTROL fields */
-#define SPI_IO_C_CLK_IDLE_HIGH        0x00000400
-#define SPI_IO_C_MX_CS_MODE           0x00000100
-#define SPI_IO_C_CS_N_POLARITY        0x000000F0
-#define SPI_IO_C_CS_N_POLARITY_0      0x00000010
-#define SPI_IO_C_CS_SELECT            0x0000000C
-#define SPI_IO_C_TRISTATE_CS          0x00000002
-#define SPI_IO_C_NO_TRI_STATE         0x00000001
-
-/* SPI_IO_MODES fields */
-#define SPI_IO_M_OUTPUT_BIT_SHIFT_EN  QSD_REG(0x00004000) QUP_REG(0x00010000)
-#define SPI_IO_M_PACK_EN              QSD_REG(0x00002000) QUP_REG(0x00008000)
-#define SPI_IO_M_UNPACK_EN            QSD_REG(0x00001000) QUP_REG(0x00004000)
-#define SPI_IO_M_INPUT_MODE           QSD_REG(0x00000C00) QUP_REG(0x00003000)
-#define SPI_IO_M_OUTPUT_MODE          QSD_REG(0x00000300) QUP_REG(0x00000C00)
-#define SPI_IO_M_INPUT_FIFO_SIZE      QSD_REG(0x000000C0) QUP_REG(0x00000380)
-#define SPI_IO_M_INPUT_BLOCK_SIZE     QSD_REG(0x00000030) QUP_REG(0x00000060)
-#define SPI_IO_M_OUTPUT_FIFO_SIZE     QSD_REG(0x0000000C) QUP_REG(0x0000001C)
-#define SPI_IO_M_OUTPUT_BLOCK_SIZE    QSD_REG(0x00000003) QUP_REG(0x00000003)
-
-#define INPUT_BLOCK_SZ_SHIFT          QSD_REG(4)          QUP_REG(5)
-#define INPUT_FIFO_SZ_SHIFT           QSD_REG(6)          QUP_REG(7)
-#define OUTPUT_BLOCK_SZ_SHIFT         QSD_REG(0)          QUP_REG(0)
-#define OUTPUT_FIFO_SZ_SHIFT          QSD_REG(2)          QUP_REG(2)
-#define OUTPUT_MODE_SHIFT             QSD_REG(8)          QUP_REG(10)
-#define INPUT_MODE_SHIFT              QSD_REG(10)         QUP_REG(12)
-
-/* SPI_OPERATIONAL fields */
-#define SPI_OP_MAX_INPUT_DONE_FLAG    0x00000800
-#define SPI_OP_MAX_OUTPUT_DONE_FLAG   0x00000400
-#define SPI_OP_INPUT_SERVICE_FLAG     0x00000200
-#define SPI_OP_OUTPUT_SERVICE_FLAG    0x00000100
-#define SPI_OP_INPUT_FIFO_FULL        0x00000080
-#define SPI_OP_OUTPUT_FIFO_FULL       0x00000040
-#define SPI_OP_IP_FIFO_NOT_EMPTY      0x00000020
-#define SPI_OP_OP_FIFO_NOT_EMPTY      0x00000010
-#define SPI_OP_STATE_VALID            0x00000004
-#define SPI_OP_STATE                  0x00000003
-
-#define SPI_OP_STATE_CLEAR_BITS       0x2
-enum msm_spi_state {
-	SPI_OP_STATE_RESET = 0x00000000,
-	SPI_OP_STATE_RUN   = 0x00000001,
-	SPI_OP_STATE_PAUSE = 0x00000003,
-};
-
-/* SPI_ERROR_FLAGS fields */
-#define SPI_ERR_OUTPUT_OVER_RUN_ERR   0x00000020
-#define SPI_ERR_INPUT_UNDER_RUN_ERR   0x00000010
-#define SPI_ERR_OUTPUT_UNDER_RUN_ERR  0x00000008
-#define SPI_ERR_INPUT_OVER_RUN_ERR    0x00000004
-#define SPI_ERR_CLK_OVER_RUN_ERR      0x00000002
-#define SPI_ERR_CLK_UNDER_RUN_ERR     0x00000001
-
-/* We don't allow transactions larger than 4K-64 or 64K-64 due to
-   mx_input/output_cnt register size */
-#define SPI_MAX_TRANSFERS             QSD_REG(0xFC0) QUP_REG(0xFC0)
-#define SPI_MAX_LEN                   (SPI_MAX_TRANSFERS * dd->bytes_per_word)
-
-#define SPI_NUM_CHIPSELECTS           4
-#define SPI_SUPPORTED_MODES  (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP)
-
-#define SPI_DELAY_THRESHOLD           1
-/* Default timeout is 10 milliseconds */
-#define SPI_DEFAULT_TIMEOUT           10
-/* 250 microseconds */
-#define SPI_TRYLOCK_DELAY             250
-
-/* Data Mover burst size */
-#define DM_BURST_SIZE                 16
-/* Data Mover commands should be aligned to 64 bit(8 bytes) */
-#define DM_BYTE_ALIGN                 8
-
-static char const * const spi_rsrcs[] = {
-	"spi_clk",
-	"spi_miso",
-	"spi_mosi"
-};
-
-static char const * const spi_cs_rsrcs[] = {
-	"spi_cs",
-	"spi_cs1",
-	"spi_cs2",
-	"spi_cs3",
-};
-
-enum msm_spi_mode {
-	SPI_FIFO_MODE  = 0x0,  /* 00 */
-	SPI_BLOCK_MODE = 0x1,  /* 01 */
-	SPI_DMOV_MODE  = 0x2,  /* 10 */
-	SPI_MODE_NONE  = 0xFF, /* invalid value */
-};
-
-/* Structure for SPI CS GPIOs */
-struct spi_cs_gpio {
-	int  gpio_num;
-	bool valid;
-};
-
-/* Structures for Data Mover */
-struct spi_dmov_cmd {
-	dmov_box box;      /* data aligned to max(dm_burst_size, block_size)
-							   (<= fifo_size) */
-	dmov_s single_pad; /* data unaligned to max(dm_burst_size, block_size)
-			      padded to fit */
-	dma_addr_t cmd_ptr;
-};
-
-MODULE_LICENSE("GPL v2");
-MODULE_VERSION("0.3");
-MODULE_ALIAS("platform:"SPI_DRV_NAME);
-
-static struct pm_qos_request_list qos_req_list;
-
-#ifdef CONFIG_DEBUG_FS
-/* Used to create debugfs entries */
-static const struct {
-	const char *name;
-	mode_t mode;
-	int offset;
-} debugfs_spi_regs[] = {
-	{"config",                S_IRUGO | S_IWUSR, SPI_CONFIG},
-	{"io_control",            S_IRUGO | S_IWUSR, SPI_IO_CONTROL},
-	{"io_modes",              S_IRUGO | S_IWUSR, SPI_IO_MODES},
-	{"sw_reset",                        S_IWUSR, SPI_SW_RESET},
-	{"time_out",              S_IRUGO | S_IWUSR, SPI_TIME_OUT},
-	{"time_out_current",      S_IRUGO,           SPI_TIME_OUT_CURRENT},
-	{"mx_output_count",       S_IRUGO | S_IWUSR, SPI_MX_OUTPUT_COUNT},
-	{"mx_output_cnt_current", S_IRUGO,           SPI_MX_OUTPUT_CNT_CURRENT},
-	{"mx_input_count",        S_IRUGO | S_IWUSR, SPI_MX_INPUT_COUNT},
-	{"mx_input_cnt_current",  S_IRUGO,           SPI_MX_INPUT_CNT_CURRENT},
-	{"mx_read_count",         S_IRUGO | S_IWUSR, SPI_MX_READ_COUNT},
-	{"mx_read_cnt_current",   S_IRUGO,           SPI_MX_READ_CNT_CURRENT},
-	{"operational",           S_IRUGO | S_IWUSR, SPI_OPERATIONAL},
-	{"error_flags",           S_IRUGO | S_IWUSR, SPI_ERROR_FLAGS},
-	{"error_flags_en",        S_IRUGO | S_IWUSR, SPI_ERROR_FLAGS_EN},
-	{"deassert_wait",         S_IRUGO | S_IWUSR, SPI_DEASSERT_WAIT},
-	{"output_debug",          S_IRUGO,           SPI_OUTPUT_DEBUG},
-	{"input_debug",           S_IRUGO,           SPI_INPUT_DEBUG},
-	{"test_ctrl",             S_IRUGO | S_IWUSR, SPI_TEST_CTRL},
-	{"output_fifo",                     S_IWUSR, SPI_OUTPUT_FIFO},
-	{"input_fifo" ,           S_IRUSR,           SPI_INPUT_FIFO},
-	{"spi_state",             S_IRUGO | S_IWUSR, SPI_STATE},
-#if defined(CONFIG_SPI_QSD) || defined(CONFIG_SPI_QSD_MODULE)
-	{"fifo_word_cnt",         S_IRUGO,           SPI_FIFO_WORD_CNT},
-#elif defined(CONFIG_SPI_QUP) || defined(CONFIG_SPI_QUP_MODULE)
-	{"qup_config",            S_IRUGO | S_IWUSR, QUP_CONFIG},
-	{"qup_error_flags",       S_IRUGO | S_IWUSR, QUP_ERROR_FLAGS},
-	{"qup_error_flags_en",    S_IRUGO | S_IWUSR, QUP_ERROR_FLAGS_EN},
-	{"mx_write_cnt",          S_IRUGO | S_IWUSR, QUP_MX_WRITE_COUNT},
-	{"mx_write_cnt_current",  S_IRUGO,           QUP_MX_WRITE_CNT_CURRENT},
-	{"output_fifo_word_cnt",  S_IRUGO,           SPI_OUTPUT_FIFO_WORD_CNT},
-	{"input_fifo_word_cnt",   S_IRUGO,           SPI_INPUT_FIFO_WORD_CNT},
-#endif
-};
-#endif
-
-struct msm_spi {
-	u8                      *read_buf;
-	const u8                *write_buf;
-	void __iomem            *base;
-	void __iomem            *gsbi_base;
-	struct device           *dev;
-	spinlock_t               queue_lock;
-	struct mutex             core_lock;
-	struct list_head         queue;
-	struct workqueue_struct *workqueue;
-	struct work_struct       work_data;
-	struct spi_message      *cur_msg;
-	struct spi_transfer     *cur_transfer;
-	struct completion        transfer_complete;
-	struct clk              *clk;
-	struct clk              *pclk;
-	unsigned long            mem_phys_addr;
-	size_t                   mem_size;
-	unsigned long            gsbi_mem_phys_addr;
-	size_t                   gsbi_mem_size;
-	int                      input_fifo_size;
-	int                      output_fifo_size;
-	u32                      rx_bytes_remaining;
-	u32                      tx_bytes_remaining;
-	u32                      clock_speed;
-	int                      irq_in;
-	int                      read_xfr_cnt;
-	int                      write_xfr_cnt;
-	int                      write_len;
-	int                      read_len;
-#if defined(CONFIG_SPI_QSD) || defined(CONFIG_SPI_QSD_MODULE)
-	int                      irq_out;
-	int                      irq_err;
-#endif
-	int                      bytes_per_word;
-	bool                     suspended;
-	bool                     transfer_pending;
-	wait_queue_head_t        continue_suspend;
-	/* DMA data */
-	enum msm_spi_mode        mode;
-	bool                     use_dma;
-	int                      tx_dma_chan;
-	int                      tx_dma_crci;
-	int                      rx_dma_chan;
-	int                      rx_dma_crci;
-	/* Data Mover Commands */
-	struct spi_dmov_cmd      *tx_dmov_cmd;
-	struct spi_dmov_cmd      *rx_dmov_cmd;
-	/* Physical address of the tx dmov box command */
-	dma_addr_t               tx_dmov_cmd_dma;
-	dma_addr_t               rx_dmov_cmd_dma;
-	struct msm_dmov_cmd      tx_hdr;
-	struct msm_dmov_cmd      rx_hdr;
-	int                      input_block_size;
-	int                      output_block_size;
-	int                      burst_size;
-	atomic_t                 rx_irq_called;
-	/* Used to pad messages unaligned to block size */
-	u8                       *tx_padding;
-	dma_addr_t               tx_padding_dma;
-	u8                       *rx_padding;
-	dma_addr_t               rx_padding_dma;
-	u32                      unaligned_len;
-	/* DMA statistics */
-	int                      stat_dmov_tx_err;
-	int                      stat_dmov_rx_err;
-	int                      stat_rx;
-	int                      stat_dmov_rx;
-	int                      stat_tx;
-	int                      stat_dmov_tx;
-#ifdef CONFIG_DEBUG_FS
-	struct dentry *dent_spi;
-	struct dentry *debugfs_spi_regs[ARRAY_SIZE(debugfs_spi_regs)];
-#endif
-	struct msm_spi_platform_data *pdata; /* Platform data */
-	/* Remote Spinlock Data */
-	bool                     use_rlock;
-	remote_mutex_t           r_lock;
-	uint32_t                 pm_lat;
-	/* When set indicates multiple transfers in a single message */
-	bool                     multi_xfr;
-	bool                     done;
-	u32                      cur_msg_len;
-	/* Used in FIFO mode to keep track of the transfer being processed */
-	struct spi_transfer     *cur_tx_transfer;
-	struct spi_transfer     *cur_rx_transfer;
-	/* Temporary buffer used for WR-WR or WR-RD transfers */
-	u8                      *temp_buf;
-	/* GPIO pin numbers for SPI clk, miso and mosi */
-	int                      spi_gpios[ARRAY_SIZE(spi_rsrcs)];
-	/* SPI CS GPIOs for each slave */
-	struct spi_cs_gpio       cs_gpios[ARRAY_SIZE(spi_cs_rsrcs)];
-};
-
-/* Forward declaration */
-static irqreturn_t msm_spi_input_irq(int irq, void *dev_id);
-static irqreturn_t msm_spi_output_irq(int irq, void *dev_id);
-static irqreturn_t msm_spi_error_irq(int irq, void *dev_id);
-static inline int msm_spi_set_state(struct msm_spi *dd,
-				    enum msm_spi_state state);
-static void msm_spi_write_word_to_fifo(struct msm_spi *dd);
-static inline void msm_spi_write_rmn_to_fifo(struct msm_spi *dd);
-
-#if defined(CONFIG_SPI_QSD) || defined(CONFIG_SPI_QSD_MODULE)
-/* Interrupt Handling */
-static inline int msm_spi_get_irq_data(struct msm_spi *dd,
-				       struct platform_device *pdev)
-{
-	dd->irq_in  = platform_get_irq_byname(pdev, "spi_irq_in");
-	dd->irq_out = platform_get_irq_byname(pdev, "spi_irq_out");
-	dd->irq_err = platform_get_irq_byname(pdev, "spi_irq_err");
-	if ((dd->irq_in < 0) || (dd->irq_out < 0) || (dd->irq_err < 0))
-		return -1;
-	return 0;
-}
-
-static inline int msm_spi_get_gsbi_resource(struct msm_spi *dd,
-					    struct platform_device *pdev)
-{
-	return 0;
-}
-
-static inline int msm_spi_request_gsbi(struct msm_spi *dd) { return 0; }
-static inline void msm_spi_release_gsbi(struct msm_spi *dd) {}
-static inline void msm_spi_init_gsbi(struct msm_spi *dd) {}
-
-static inline void msm_spi_disable_irqs(struct msm_spi *dd)
-{
-	disable_irq(dd->irq_in);
-	disable_irq(dd->irq_out);
-	disable_irq(dd->irq_err);
-}
-
-static inline void msm_spi_enable_irqs(struct msm_spi *dd)
-{
-	enable_irq(dd->irq_in);
-	enable_irq(dd->irq_out);
-	enable_irq(dd->irq_err);
-}
-
-static inline int msm_spi_request_irq(struct msm_spi *dd,
-				      const char *name,
-				      struct spi_master *master)
-{
-	int rc;
-	rc = request_irq(dd->irq_in, msm_spi_input_irq, IRQF_TRIGGER_RISING,
-			   name, dd);
-	if (rc)
-		goto error_irq1;
-	rc = request_irq(dd->irq_out, msm_spi_output_irq, IRQF_TRIGGER_RISING,
-			   name, dd);
-	if (rc)
-		goto error_irq2;
-	rc = request_irq(dd->irq_err, msm_spi_error_irq, IRQF_TRIGGER_RISING,
-			   name, master);
-	if (rc)
-		goto error_irq3;
-	return 0;
-
-error_irq3:
-	free_irq(dd->irq_out, dd);
-error_irq2:
-	free_irq(dd->irq_in, dd);
-error_irq1:
-	return rc;
-}
-
-static inline void msm_spi_free_irq(struct msm_spi *dd,
-				    struct spi_master *master)
-{
-	free_irq(dd->irq_err, master);
-	free_irq(dd->irq_out, dd);
-	free_irq(dd->irq_in, dd);
-}
-
-static inline void msm_spi_get_clk_err(struct msm_spi *dd, u32 *spi_err) {}
-static inline void msm_spi_ack_clk_err(struct msm_spi *dd) {}
-static inline void msm_spi_set_qup_config(struct msm_spi *dd, int bpw) {}
-
-static inline int msm_spi_prepare_for_write(struct msm_spi *dd) { return 0; }
-static inline void msm_spi_start_write(struct msm_spi *dd, u32 read_count)
-{
-	msm_spi_write_word_to_fifo(dd);
-}
-static inline void msm_spi_set_write_count(struct msm_spi *dd, int val) {}
-
-static inline void msm_spi_complete(struct msm_spi *dd)
-{
-	complete(&dd->transfer_complete);
-}
-
-static inline void msm_spi_enable_error_flags(struct msm_spi *dd)
-{
-	writel_relaxed(0x0000007B, dd->base + SPI_ERROR_FLAGS_EN);
-}
-
-static inline void msm_spi_clear_error_flags(struct msm_spi *dd)
-{
-	writel_relaxed(0x0000007F, dd->base + SPI_ERROR_FLAGS);
-}
-
-#elif defined(CONFIG_SPI_QUP) || defined(CONFIG_SPI_QUP_MODULE)
-
-/* Interrupt Handling */
-/* In QUP the same interrupt line is used for intput, output and error*/
-static inline int msm_spi_get_irq_data(struct msm_spi *dd,
-				       struct platform_device *pdev)
-{
-	dd->irq_in  = platform_get_irq_byname(pdev, "spi_irq_in");
-	if (dd->irq_in < 0)
-		return -1;
-	return 0;
-}
-
-static inline int msm_spi_get_gsbi_resource(struct msm_spi *dd,
-				       struct platform_device *pdev)
+static inline int msm_spi_configure_gsbi(struct msm_spi *dd,
+					struct platform_device *pdev)
 {
 	struct resource *resource;
+	unsigned long   gsbi_mem_phys_addr;
+	size_t          gsbi_mem_size;
+	void __iomem    *gsbi_base;
 
-	resource  = platform_get_resource_byname(pdev,
-						 IORESOURCE_MEM, "gsbi_base");
+	resource  = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 	if (!resource)
+		return 0;
+
+	gsbi_mem_phys_addr = resource->start;
+	gsbi_mem_size = resource_size(resource);
+	if (!devm_request_mem_region(&pdev->dev, gsbi_mem_phys_addr,
+					gsbi_mem_size, SPI_DRV_NAME))
 		return -ENXIO;
-	dd->gsbi_mem_phys_addr = resource->start;
-	dd->gsbi_mem_size = resource_size(resource);
+
+	gsbi_base = devm_ioremap(&pdev->dev, gsbi_mem_phys_addr,
+					gsbi_mem_size);
+	if (!gsbi_base)
+		return -ENXIO;
+
+	/* Set GSBI to SPI mode */
+	writel_relaxed(GSBI_SPI_CONFIG, gsbi_base + GSBI_CTRL_REG);
 
 	return 0;
 }
 
-static inline void msm_spi_release_gsbi(struct msm_spi *dd)
+static inline void msm_spi_register_init(struct msm_spi *dd)
 {
-	iounmap(dd->gsbi_base);
-	release_mem_region(dd->gsbi_mem_phys_addr, dd->gsbi_mem_size);
+	writel_relaxed(0x00000001, dd->base + SPI_SW_RESET);
+	msm_spi_set_state(dd, SPI_OP_STATE_RESET);
+	writel_relaxed(0x00000000, dd->base + SPI_OPERATIONAL);
+	writel_relaxed(0x00000000, dd->base + SPI_CONFIG);
+	writel_relaxed(0x00000000, dd->base + SPI_IO_MODES);
+	if (dd->qup_ver)
+		writel_relaxed(0x00000000, dd->base + QUP_OPERATIONAL_MASK);
 }
 
-static inline int msm_spi_request_gsbi(struct msm_spi *dd)
-{
-	if (!request_mem_region(dd->gsbi_mem_phys_addr, dd->gsbi_mem_size,
-				SPI_DRV_NAME)) {
-		return -ENXIO;
-	}
-	dd->gsbi_base = ioremap(dd->gsbi_mem_phys_addr, dd->gsbi_mem_size);
-	if (!dd->gsbi_base) {
-		release_mem_region(dd->gsbi_mem_phys_addr, dd->gsbi_mem_size);
-		return -ENXIO;
-	}
-	return 0;
-}
-
-static inline void msm_spi_init_gsbi(struct msm_spi *dd)
-{
-	/* Set GSBI to SPI mode, and CRCI_MUX_CTRL to SPI CRCI ports */
-	writel_relaxed(GSBI_SPI_CONFIG, dd->gsbi_base + GSBI_CTRL_REG);
-}
-
-/* Figure which irq occured and call the relevant functions */
-static irqreturn_t msm_spi_qup_irq(int irq, void *dev_id)
-{
-	u32 op, ret = IRQ_NONE;
-	struct msm_spi *dd = dev_id;
-
-	if (readl_relaxed(dd->base + SPI_ERROR_FLAGS) ||
-	    readl_relaxed(dd->base + QUP_ERROR_FLAGS)) {
-		struct spi_master *master = dev_get_drvdata(dd->dev);
-		ret |= msm_spi_error_irq(irq, master);
-	}
-
-	op = readl_relaxed(dd->base + SPI_OPERATIONAL);
-	if (op & SPI_OP_INPUT_SERVICE_FLAG) {
-		writel_relaxed(SPI_OP_INPUT_SERVICE_FLAG,
-			       dd->base + SPI_OPERATIONAL);
-		/*
-		 * Ensure service flag was cleared before further
-		 * processing of interrupt.
-		 */
-		mb();
-		ret |= msm_spi_input_irq(irq, dev_id);
-	}
-
-	if (op & SPI_OP_OUTPUT_SERVICE_FLAG) {
-		writel_relaxed(SPI_OP_OUTPUT_SERVICE_FLAG,
-			       dd->base + SPI_OPERATIONAL);
-		/*
-		 * Ensure service flag was cleared before further
-		 * processing of interrupt.
-		 */
-		mb();
-		ret |= msm_spi_output_irq(irq, dev_id);
-	}
-
-	if (dd->done) {
-		complete(&dd->transfer_complete);
-		dd->done = 0;
-	}
-	return ret;
-}
-
-static inline int msm_spi_request_irq(struct msm_spi *dd,
-				      const char *name,
-				      struct spi_master *master)
-{
-	return request_irq(dd->irq_in, msm_spi_qup_irq, IRQF_TRIGGER_HIGH,
-			   name, dd);
-}
-
-static inline void msm_spi_free_irq(struct msm_spi *dd,
-				    struct spi_master *master)
-{
-	free_irq(dd->irq_in, dd);
-}
-
-static inline void msm_spi_free_output_irq(struct msm_spi *dd) { }
-static inline void msm_spi_free_error_irq(struct msm_spi *dd,
-					  struct spi_master *master) { }
-
-static inline void msm_spi_disable_irqs(struct msm_spi *dd)
-{
-	disable_irq(dd->irq_in);
-}
-
-static inline void msm_spi_enable_irqs(struct msm_spi *dd)
-{
-	enable_irq(dd->irq_in);
-}
-
-static inline void msm_spi_get_clk_err(struct msm_spi *dd, u32 *spi_err)
-{
-	*spi_err = readl_relaxed(dd->base + QUP_ERROR_FLAGS);
-}
-
-static inline void msm_spi_ack_clk_err(struct msm_spi *dd)
-{
-	writel_relaxed(QUP_ERR_MASK, dd->base + QUP_ERROR_FLAGS);
-}
-
-static inline void msm_spi_add_configs(struct msm_spi *dd, u32 *config, int n);
-
-/* QUP has no_input, no_output, and N bits at QUP_CONFIG */
-static inline void msm_spi_set_qup_config(struct msm_spi *dd, int bpw)
-{
-	u32 qup_config = readl_relaxed(dd->base + QUP_CONFIG);
-
-	msm_spi_add_configs(dd, &qup_config, bpw-1);
-	writel_relaxed(qup_config | QUP_CONFIG_SPI_MODE,
-		       dd->base + QUP_CONFIG);
-}
-
-static inline int msm_spi_prepare_for_write(struct msm_spi *dd)
-{
-	if (msm_spi_set_state(dd, SPI_OP_STATE_RUN))
-		return -1;
-	if (msm_spi_set_state(dd, SPI_OP_STATE_PAUSE))
-		return -1;
-	return 0;
-}
-
-static inline void msm_spi_start_write(struct msm_spi *dd, u32 read_count)
-{
-	if (read_count <= dd->input_fifo_size)
-		msm_spi_write_rmn_to_fifo(dd);
-	else
-		msm_spi_write_word_to_fifo(dd);
-}
-
-static inline void msm_spi_set_write_count(struct msm_spi *dd, int val)
-{
-	writel_relaxed(val, dd->base + QUP_MX_WRITE_COUNT);
-}
-
-static inline void msm_spi_complete(struct msm_spi *dd)
-{
-	dd->done = 1;
-}
-
-static inline void msm_spi_enable_error_flags(struct msm_spi *dd)
-{
-	writel_relaxed(0x00000078, dd->base + SPI_ERROR_FLAGS_EN);
-}
-
-static inline void msm_spi_clear_error_flags(struct msm_spi *dd)
-{
-	writel_relaxed(0x0000007C, dd->base + SPI_ERROR_FLAGS);
-}
-
-#endif
-
 static inline int msm_spi_request_gpios(struct msm_spi *dd)
 {
 	int i;
@@ -710,8 +151,9 @@
 		words = 8; /* 32 bytes */
 		break;
 	default:
-		return -1;
+		return -EINVAL;
 	}
+
 	switch (mult) {
 	case 0:
 		*fifo_size = words * 2;
@@ -726,8 +168,9 @@
 		*fifo_size = words * 16;
 		break;
 	default:
-		return -1;
+		return -EINVAL;
 	}
+
 	*block_size = words * sizeof(u32); /* in bytes */
 	return 0;
 }
@@ -781,8 +224,7 @@
 
 fifo_size_err:
 	dd->use_dma = 0;
-	printk(KERN_WARNING "%s: invalid FIFO size, SPI_IO_MODES=0x%x\n",
-	       __func__, spi_iom);
+	pr_err("%s: invalid FIFO size, SPI_IO_MODES=0x%x\n", __func__, spi_iom);
 	return;
 }
 
@@ -812,6 +254,7 @@
 		else
 			dd->rx_bytes_remaining = 0;
 	}
+
 	dd->read_xfr_cnt++;
 	if (dd->multi_xfr) {
 		if (!dd->rx_bytes_remaining)
@@ -889,7 +332,7 @@
 {
 	enum msm_spi_state cur_state;
 	if (msm_spi_wait_valid(dd))
-		return -1;
+		return -EIO;
 	cur_state = readl_relaxed(dd->base + SPI_STATE);
 	/* Per spec:
 	   For PAUSE_STATE to RESET_STATE, two writes of (10) are required */
@@ -902,7 +345,7 @@
 		       dd->base + SPI_STATE);
 	}
 	if (msm_spi_wait_valid(dd))
-		return -1;
+		return -EIO;
 
 	return 0;
 }
@@ -1121,6 +564,48 @@
 	mb();
 }
 
+/* Figure which irq occured and call the relevant functions */
+static inline irqreturn_t msm_spi_qup_irq(int irq, void *dev_id)
+{
+	u32 op, ret = IRQ_NONE;
+	struct msm_spi *dd = dev_id;
+
+	if (readl_relaxed(dd->base + SPI_ERROR_FLAGS) ||
+	    readl_relaxed(dd->base + QUP_ERROR_FLAGS)) {
+		struct spi_master *master = dev_get_drvdata(dd->dev);
+		ret |= msm_spi_error_irq(irq, master);
+	}
+
+	op = readl_relaxed(dd->base + SPI_OPERATIONAL);
+	if (op & SPI_OP_INPUT_SERVICE_FLAG) {
+		writel_relaxed(SPI_OP_INPUT_SERVICE_FLAG,
+			       dd->base + SPI_OPERATIONAL);
+		/*
+		 * Ensure service flag was cleared before further
+		 * processing of interrupt.
+		 */
+		mb();
+		ret |= msm_spi_input_irq(irq, dev_id);
+	}
+
+	if (op & SPI_OP_OUTPUT_SERVICE_FLAG) {
+		writel_relaxed(SPI_OP_OUTPUT_SERVICE_FLAG,
+			       dd->base + SPI_OPERATIONAL);
+		/*
+		 * Ensure service flag was cleared before further
+		 * processing of interrupt.
+		 */
+		mb();
+		ret |= msm_spi_output_irq(irq, dev_id);
+	}
+
+	if (dd->done) {
+		complete(&dd->transfer_complete);
+		dd->done = 0;
+	}
+	return ret;
+}
+
 static irqreturn_t msm_spi_input_irq(int irq, void *dev_id)
 {
 	struct msm_spi	       *dd = dev_id;
@@ -1490,14 +975,14 @@
 	if (int_loopback && dd->multi_xfr &&
 			(read_count > dd->input_fifo_size)) {
 		if (dd->read_len && dd->write_len)
-			printk(KERN_WARNING
-			"%s:Internal Loopback does not support > fifo size\
-			for write-then-read transactions\n",
+			pr_err(
+			"%s:Internal Loopback does not support > fifo size"
+			"for write-then-read transactions\n",
 			__func__);
 		else if (dd->write_len && !dd->read_len)
-			printk(KERN_WARNING
-			"%s:Internal Loopback does not support > fifo size\
-			for write-then-write transactions\n",
+			pr_err(
+			"%s:Internal Loopback does not support > fifo size"
+			"for write-then-write transactions\n",
 			__func__);
 		return;
 	}
@@ -1692,43 +1177,84 @@
 		dd->cs_gpios[cs_num].valid = 1;
 	}
 
-	dd->cur_transfer = list_first_entry(&dd->cur_msg->transfers,
-					    struct spi_transfer,
-					    transfer_list);
-	get_transfer_length(dd);
-	if (dd->multi_xfr && !dd->read_len && !dd->write_len) {
-		/* Handling of multi-transfers. FIFO mode is used by default */
+	if (dd->qup_ver) {
 		list_for_each_entry(dd->cur_transfer,
-				    &dd->cur_msg->transfers,
-				    transfer_list) {
-			if (!dd->cur_transfer->len)
-				goto error;
-			if (xfrs_grped) {
-				xfrs_grped--;
-				continue;
-			} else {
-				dd->read_len = dd->write_len = 0;
-				xfrs_grped = combine_transfers(dd);
+				&dd->cur_msg->transfers,
+				transfer_list) {
+			u32 spi_ioc;
+			u32 spi_ioc_orig;
+			struct spi_transfer *t = dd->cur_transfer;
+			struct spi_transfer *nxt;
+
+			if (t->transfer_list.next != &dd->cur_msg->transfers) {
+				nxt = list_entry(t->transfer_list.next,
+						struct spi_transfer,
+						transfer_list);
+
+				spi_ioc = readl_relaxed(dd->base +
+							SPI_IO_CONTROL);
+				spi_ioc_orig = spi_ioc;
+				if (t->cs_change == nxt->cs_change)
+					spi_ioc |= SPI_IO_C_FORCE_CS;
+				else
+					spi_ioc &= ~SPI_IO_C_FORCE_CS;
+
+				if (spi_ioc != spi_ioc_orig) {
+					writel_relaxed(spi_ioc,
+						dd->base + SPI_IO_CONTROL);
+				}
 			}
+
+			dd->cur_msg_len = dd->cur_transfer->len;
+			msm_spi_process_transfer(dd);
+		}
+	} else {
+		dd->cur_transfer = list_first_entry(&dd->cur_msg->transfers,
+						    struct spi_transfer,
+						    transfer_list);
+		get_transfer_length(dd);
+		if (dd->multi_xfr && !dd->read_len && !dd->write_len) {
+			/*
+			 * Handling of multi-transfers.
+			 * FIFO mode is used by default
+			 */
+			list_for_each_entry(dd->cur_transfer,
+					    &dd->cur_msg->transfers,
+					    transfer_list) {
+				if (!dd->cur_transfer->len)
+					goto error;
+				if (xfrs_grped) {
+					xfrs_grped--;
+					continue;
+				} else {
+					dd->read_len = dd->write_len = 0;
+					xfrs_grped = combine_transfers(dd);
+				}
+
+				dd->cur_tx_transfer = dd->cur_transfer;
+				dd->cur_rx_transfer = dd->cur_transfer;
+				msm_spi_process_transfer(dd);
+				xfrs_grped--;
+			}
+		} else {
+			/* Handling of a single transfer or
+			 * WR-WR or WR-RD transfers
+			 */
+			if ((!dd->cur_msg->is_dma_mapped) &&
+			    (msm_use_dm(dd, dd->cur_transfer,
+					dd->cur_transfer->bits_per_word))) {
+				/* Mapping of DMA buffers */
+				int ret = msm_spi_map_dma_buffers(dd);
+				if (ret < 0) {
+					dd->cur_msg->status = ret;
+					goto error;
+				}
+			}
+
 			dd->cur_tx_transfer = dd->cur_transfer;
 			dd->cur_rx_transfer = dd->cur_transfer;
 			msm_spi_process_transfer(dd);
-			xfrs_grped--;
 		}
-	} else {
-		/* Handling of a single transfer or WR-WR or WR-RD transfers */
-		if ((!dd->cur_msg->is_dma_mapped) &&
-		    (msm_use_dm(dd, dd->cur_transfer,
-				dd->cur_transfer->bits_per_word))) {
-			/* Mapping of DMA buffers */
-			int ret = msm_spi_map_dma_buffers(dd);
-			if (ret < 0) {
-				dd->cur_msg->status = ret;
-				goto error;
-			}
-		}
-		dd->cur_tx_transfer = dd->cur_rx_transfer = dd->cur_transfer;
-		msm_spi_process_transfer(dd);
 	}
 
 	return;
@@ -1939,6 +1465,7 @@
 	dd->dent_spi = debugfs_create_dir(dev_name(dd->dev), NULL);
 	if (dd->dent_spi) {
 		int i;
+
 		for (i = 0; i < ARRAY_SIZE(debugfs_spi_regs); i++) {
 			dd->debugfs_spi_regs[i] =
 			   debugfs_create_file(
@@ -1955,6 +1482,7 @@
 {
 	if (dd->dent_spi) {
 		int i;
+
 		debugfs_remove_recursive(dd->dent_spi);
 		dd->dent_spi = NULL;
 		for (i = 0; i < ARRAY_SIZE(debugfs_spi_regs); i++)
@@ -2210,6 +1738,23 @@
 	return 0;
 }
 
+struct msm_spi_platform_data *msm_spi_dt_to_pdata(struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct msm_spi_platform_data *pdata;
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		pr_err("Unable to allocate platform data\n");
+		return NULL;
+	}
+
+	of_property_read_u32(node, "spi-max-frequency",
+			&pdata->max_clock_speed);
+
+	return pdata;
+}
+
 static int __init msm_spi_probe(struct platform_device *pdev)
 {
 	struct spi_master      *master;
@@ -2220,7 +1765,7 @@
 	int                     i = 0;
 	int                     clk_enabled = 0;
 	int                     pclk_enabled = 0;
-	struct msm_spi_platform_data *pdata = pdev->dev.platform_data;
+	struct msm_spi_platform_data *pdata;
 
 	master = spi_alloc_master(&pdev->dev, sizeof(struct msm_spi));
 	if (!master) {
@@ -2237,23 +1782,29 @@
 	platform_set_drvdata(pdev, master);
 	dd = spi_master_get_devdata(master);
 
+	if (pdev->dev.of_node) {
+		dd->qup_ver = SPI_QUP_VERSION_BFAM;
+		master->dev.of_node = pdev->dev.of_node;
+		pdata = msm_spi_dt_to_pdata(pdev);
+		if (!pdata) {
+			rc = -ENOMEM;
+			goto err_probe_exit;
+		}
+	} else {
+		pdata = pdev->dev.platform_data;
+		dd->qup_ver = SPI_QUP_VERSION_NONE;
+	}
+
 	dd->pdata = pdata;
-	rc = msm_spi_get_irq_data(dd, pdev);
-	if (rc)
-		goto err_probe_res;
-	resource = platform_get_resource_byname(pdev,
-						 IORESOURCE_MEM, "spi_base");
+	resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!resource) {
 		rc = -ENXIO;
 		goto err_probe_res;
 	}
+
 	dd->mem_phys_addr = resource->start;
 	dd->mem_size = resource_size(resource);
 
-	rc = msm_spi_get_gsbi_resource(dd, pdev);
-	if (rc)
-		goto err_probe_res2;
-
 	if (pdata) {
 		if (pdata->dma_config) {
 			rc = pdata->dma_config();
@@ -2265,20 +1816,17 @@
 				goto skip_dma_resources;
 			}
 		}
-		resource = platform_get_resource_byname(pdev,
-							IORESOURCE_DMA,
-							"spidm_channels");
+		resource = platform_get_resource(pdev, IORESOURCE_DMA, 0);
 		if (resource) {
 			dd->rx_dma_chan = resource->start;
 			dd->tx_dma_chan = resource->end;
-
-			resource = platform_get_resource_byname(pdev,
-							IORESOURCE_DMA,
-							"spidm_crci");
+			resource = platform_get_resource(pdev, IORESOURCE_DMA,
+							1);
 			if (!resource) {
 				rc = -ENXIO;
 				goto err_probe_res;
 			}
+
 			dd->rx_dma_crci = resource->start;
 			dd->tx_dma_crci = resource->end;
 			dd->use_dma = 1;
@@ -2298,14 +1846,13 @@
 	}
 
 	for (i = 0; i < ARRAY_SIZE(spi_rsrcs); ++i) {
-		resource = platform_get_resource_byname(pdev, IORESOURCE_IO,
-							spi_rsrcs[i]);
+		resource = platform_get_resource(pdev, IORESOURCE_IO, i);
 		dd->spi_gpios[i] = resource ? resource->start : -1;
 	}
 
 	for (i = 0; i < ARRAY_SIZE(spi_cs_rsrcs); ++i) {
-		resource = platform_get_resource_byname(pdev, IORESOURCE_IO,
-							spi_cs_rsrcs[i]);
+		resource = platform_get_resource(pdev, IORESOURCE_IO,
+				i + ARRAY_SIZE(spi_rsrcs));
 		dd->cs_gpios[i].gpio_num = resource ? resource->start : -1;
 		dd->cs_gpios[i].valid = 0;
 	}
@@ -2320,22 +1867,22 @@
 	INIT_WORK(&dd->work_data, msm_spi_workq);
 	init_waitqueue_head(&dd->continue_suspend);
 	dd->workqueue = create_singlethread_workqueue(
-		dev_name(master->dev.parent));
+			dev_name(master->dev.parent));
 	if (!dd->workqueue)
 		goto err_probe_workq;
 
-	if (!request_mem_region(dd->mem_phys_addr, dd->mem_size,
-				SPI_DRV_NAME)) {
+	if (!devm_request_mem_region(&pdev->dev, dd->mem_phys_addr,
+					dd->mem_size, SPI_DRV_NAME)) {
 		rc = -ENXIO;
 		goto err_probe_reqmem;
 	}
 
-	dd->base = ioremap(dd->mem_phys_addr, dd->mem_size);
-	if (!dd->base)
-		goto err_probe_ioremap;
-	rc = msm_spi_request_gsbi(dd);
-	if (rc)
-		goto err_probe_ioremap2;
+	dd->base = devm_ioremap(&pdev->dev, dd->mem_phys_addr, dd->mem_size);
+	if (!dd->base) {
+		rc = -ENOMEM;
+		goto err_probe_reqmem;
+	}
+
 	if (pdata && pdata->rsl_id) {
 		struct remote_mutex_id rmid;
 		rmid.r_spinlock_id = pdata->rsl_id;
@@ -2348,16 +1895,18 @@
 				__func__, rc);
 			goto err_probe_rlock_init;
 		}
+
 		dd->use_rlock = 1;
 		dd->pm_lat = pdata->pm_lat;
 		pm_qos_add_request(&qos_req_list, PM_QOS_CPU_DMA_LATENCY, 
 					    	 PM_QOS_DEFAULT_VALUE);
 	}
+
 	mutex_lock(&dd->core_lock);
 	if (dd->use_rlock)
 		remote_mutex_lock(&dd->r_lock);
-	locked = 1;
 
+	locked = 1;
 	dd->dev = &pdev->dev;
 	dd->clk = clk_get(&pdev->dev, "core_clk");
 	if (IS_ERR(dd->clk)) {
@@ -2382,16 +1931,20 @@
 			__func__);
 		goto err_probe_clk_enable;
 	}
-	clk_enabled = 1;
 
+	clk_enabled = 1;
 	rc = clk_enable(dd->pclk);
 	if (rc) {
 		dev_err(&pdev->dev, "%s: unable to enable iface_clk\n",
 		__func__);
 		goto err_probe_pclk_enable;
 	}
+
 	pclk_enabled = 1;
-	msm_spi_init_gsbi(dd);
+	rc = msm_spi_configure_gsbi(dd, pdev);
+	if (rc)
+		goto err_probe_gsbi;
+
 	msm_spi_calculate_fifo_size(dd);
 	if (dd->use_dma) {
 		rc = msm_spi_init_dma(dd);
@@ -2399,13 +1952,7 @@
 			goto err_probe_dma;
 	}
 
-	/* Initialize registers */
-	writel_relaxed(0x00000001, dd->base + SPI_SW_RESET);
-	msm_spi_set_state(dd, SPI_OP_STATE_RESET);
-
-	writel_relaxed(0x00000000, dd->base + SPI_OPERATIONAL);
-	writel_relaxed(0x00000000, dd->base + SPI_CONFIG);
-	writel_relaxed(0x00000000, dd->base + SPI_IO_MODES);
+	msm_spi_register_init(dd);
 	/*
 	 * The SPI core generates a bogus input overrun error on some targets,
 	 * when a transition from run to reset state occurs and if the FIFO has
@@ -2429,7 +1976,7 @@
 	dd->multi_xfr = 0;
 	dd->mode = SPI_MODE_NONE;
 
-	rc = msm_spi_request_irq(dd, pdev->name, master);
+	rc = msm_spi_request_irq(dd, pdev, master);
 	if (rc)
 		goto err_probe_irq;
 
@@ -2451,16 +1998,16 @@
 	}
 
 	spi_debugfs_init(dd);
-
 	return 0;
 
 err_attrs:
+	spi_unregister_master(master);
 err_probe_reg_master:
-	msm_spi_free_irq(dd, master);
 err_probe_irq:
 err_probe_state:
 	msm_spi_teardown_dma(dd);
 err_probe_dma:
+err_probe_gsbi:
 	if (pclk_enabled)
 		clk_disable(dd->pclk);
 err_probe_pclk_enable:
@@ -2474,14 +2021,10 @@
 	if (locked) {
 		if (dd->use_rlock)
 			remote_mutex_unlock(&dd->r_lock);
+
 		mutex_unlock(&dd->core_lock);
 	}
 err_probe_rlock_init:
-	msm_spi_release_gsbi(dd);
-err_probe_ioremap2:
-	iounmap(dd->base);
-err_probe_ioremap:
-	release_mem_region(dd->mem_phys_addr, dd->mem_size);
 err_probe_reqmem:
 	destroy_workqueue(dd->workqueue);
 err_probe_workq:
@@ -2489,7 +2032,6 @@
 err_probe_gpio:
 	if (pdata && pdata->gpio_release)
 		pdata->gpio_release();
-err_probe_res2:
 err_probe_res:
 	spi_master_put(master);
 err_probe_exit:
@@ -2553,16 +2095,11 @@
 	spi_debugfs_exit(dd);
 	sysfs_remove_group(&pdev->dev.kobj, &dev_attr_grp);
 
-	msm_spi_free_irq(dd, master);
 	msm_spi_teardown_dma(dd);
-
 	if (pdata && pdata->gpio_release)
 		pdata->gpio_release();
 
 	msm_spi_free_gpios(dd);
-	iounmap(dd->base);
-	release_mem_region(dd->mem_phys_addr, dd->mem_size);
-	msm_spi_release_gsbi(dd);
 	clk_put(dd->clk);
 	clk_put(dd->pclk);
 	destroy_workqueue(dd->workqueue);
@@ -2573,10 +2110,18 @@
 	return 0;
 }
 
+static struct of_device_id msm_spi_dt_match[] = {
+	{
+		.compatible = "qcom,spi-qup-v2",
+	},
+	{}
+};
+
 static struct platform_driver msm_spi_driver = {
 	.driver		= {
 		.name	= SPI_DRV_NAME,
 		.owner	= THIS_MODULE,
+		.of_match_table = msm_spi_dt_match,
 	},
 	.suspend        = msm_spi_suspend,
 	.resume         = msm_spi_resume,
@@ -2594,3 +2139,7 @@
 	platform_driver_unregister(&msm_spi_driver);
 }
 module_exit(msm_spi_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("0.4");
+MODULE_ALIAS("platform:"SPI_DRV_NAME);
diff --git a/drivers/spi/spi_qsd.h b/drivers/spi/spi_qsd.h
new file mode 100644
index 0000000..bda9e17
--- /dev/null
+++ b/drivers/spi/spi_qsd.h
@@ -0,0 +1,492 @@
+/* Copyright (c) 2008-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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _SPI_QSD_H
+#define _SPI_QSD_H
+
+#define SPI_DRV_NAME                  "spi_qsd"
+
+#if defined(CONFIG_SPI_QSD) || defined(CONFIG_SPI_QSD_MODULE)
+
+#define QSD_REG(x) (x)
+#define QUP_REG(x)
+
+#define SPI_FIFO_WORD_CNT             0x0048
+
+#else
+
+#define QSD_REG(x)
+#define QUP_REG(x) (x)
+
+#define QUP_CONFIG                    0x0000 /* N & NO_INPUT/NO_OUPUT bits */
+#define QUP_ERROR_FLAGS_EN            0x030C
+#define QUP_ERR_MASK                  0x3
+#define SPI_OUTPUT_FIFO_WORD_CNT      0x010C
+#define SPI_INPUT_FIFO_WORD_CNT       0x0214
+#define QUP_MX_WRITE_COUNT            0x0150
+#define QUP_MX_WRITE_CNT_CURRENT      0x0154
+
+#define QUP_CONFIG_SPI_MODE           0x0100
+#endif
+
+#define GSBI_CTRL_REG                 0x0
+#define GSBI_SPI_CONFIG               0x30
+#define QUP_HARDWARE_VER              0x0030
+#define QUP_OPERATIONAL_MASK          0x0028
+#define QUP_ERROR_FLAGS               0x0308
+
+#define SPI_CONFIG                    QSD_REG(0x0000) QUP_REG(0x0300)
+#define SPI_IO_CONTROL                QSD_REG(0x0004) QUP_REG(0x0304)
+#define SPI_IO_MODES                  QSD_REG(0x0008) QUP_REG(0x0008)
+#define SPI_SW_RESET                  QSD_REG(0x000C) QUP_REG(0x000C)
+#define SPI_TIME_OUT_CURRENT          QSD_REG(0x0014) QUP_REG(0x0014)
+#define SPI_MX_OUTPUT_COUNT           QSD_REG(0x0018) QUP_REG(0x0100)
+#define SPI_MX_OUTPUT_CNT_CURRENT     QSD_REG(0x001C) QUP_REG(0x0104)
+#define SPI_MX_INPUT_COUNT            QSD_REG(0x0020) QUP_REG(0x0200)
+#define SPI_MX_INPUT_CNT_CURRENT      QSD_REG(0x0024) QUP_REG(0x0204)
+#define SPI_MX_READ_COUNT             QSD_REG(0x0028) QUP_REG(0x0208)
+#define SPI_MX_READ_CNT_CURRENT       QSD_REG(0x002C) QUP_REG(0x020C)
+#define SPI_OPERATIONAL               QSD_REG(0x0030) QUP_REG(0x0018)
+#define SPI_ERROR_FLAGS               QSD_REG(0x0034) QUP_REG(0x001C)
+#define SPI_ERROR_FLAGS_EN            QSD_REG(0x0038) QUP_REG(0x0020)
+#define SPI_DEASSERT_WAIT             QSD_REG(0x003C) QUP_REG(0x0310)
+#define SPI_OUTPUT_DEBUG              QSD_REG(0x0040) QUP_REG(0x0108)
+#define SPI_INPUT_DEBUG               QSD_REG(0x0044) QUP_REG(0x0210)
+#define SPI_TEST_CTRL                 QSD_REG(0x004C) QUP_REG(0x0024)
+#define SPI_OUTPUT_FIFO               QSD_REG(0x0100) QUP_REG(0x0110)
+#define SPI_INPUT_FIFO                QSD_REG(0x0200) QUP_REG(0x0218)
+#define SPI_STATE                     QSD_REG(SPI_OPERATIONAL) QUP_REG(0x0004)
+
+/* SPI_CONFIG fields */
+#define SPI_CFG_INPUT_FIRST           0x00000200
+#define SPI_NO_INPUT                  0x00000080
+#define SPI_NO_OUTPUT                 0x00000040
+#define SPI_CFG_LOOPBACK              0x00000100
+#define SPI_CFG_N                     0x0000001F
+
+/* SPI_IO_CONTROL fields */
+#define SPI_IO_C_FORCE_CS             0x00000800
+#define SPI_IO_C_CLK_IDLE_HIGH        0x00000400
+#define SPI_IO_C_MX_CS_MODE           0x00000100
+#define SPI_IO_C_CS_N_POLARITY        0x000000F0
+#define SPI_IO_C_CS_N_POLARITY_0      0x00000010
+#define SPI_IO_C_CS_SELECT            0x0000000C
+#define SPI_IO_C_TRISTATE_CS          0x00000002
+#define SPI_IO_C_NO_TRI_STATE         0x00000001
+
+/* SPI_IO_MODES fields */
+#define SPI_IO_M_OUTPUT_BIT_SHIFT_EN  QSD_REG(0x00004000) QUP_REG(0x00010000)
+#define SPI_IO_M_PACK_EN              QSD_REG(0x00002000) QUP_REG(0x00008000)
+#define SPI_IO_M_UNPACK_EN            QSD_REG(0x00001000) QUP_REG(0x00004000)
+#define SPI_IO_M_INPUT_MODE           QSD_REG(0x00000C00) QUP_REG(0x00003000)
+#define SPI_IO_M_OUTPUT_MODE          QSD_REG(0x00000300) QUP_REG(0x00000C00)
+#define SPI_IO_M_INPUT_FIFO_SIZE      QSD_REG(0x000000C0) QUP_REG(0x00000380)
+#define SPI_IO_M_INPUT_BLOCK_SIZE     QSD_REG(0x00000030) QUP_REG(0x00000060)
+#define SPI_IO_M_OUTPUT_FIFO_SIZE     QSD_REG(0x0000000C) QUP_REG(0x0000001C)
+#define SPI_IO_M_OUTPUT_BLOCK_SIZE    QSD_REG(0x00000003) QUP_REG(0x00000003)
+
+#define INPUT_BLOCK_SZ_SHIFT          QSD_REG(4)          QUP_REG(5)
+#define INPUT_FIFO_SZ_SHIFT           QSD_REG(6)          QUP_REG(7)
+#define OUTPUT_BLOCK_SZ_SHIFT         QSD_REG(0)          QUP_REG(0)
+#define OUTPUT_FIFO_SZ_SHIFT          QSD_REG(2)          QUP_REG(2)
+#define OUTPUT_MODE_SHIFT             QSD_REG(8)          QUP_REG(10)
+#define INPUT_MODE_SHIFT              QSD_REG(10)         QUP_REG(12)
+
+/* SPI_OPERATIONAL fields */
+#define SPI_OP_MAX_INPUT_DONE_FLAG    0x00000800
+#define SPI_OP_MAX_OUTPUT_DONE_FLAG   0x00000400
+#define SPI_OP_INPUT_SERVICE_FLAG     0x00000200
+#define SPI_OP_OUTPUT_SERVICE_FLAG    0x00000100
+#define SPI_OP_INPUT_FIFO_FULL        0x00000080
+#define SPI_OP_OUTPUT_FIFO_FULL       0x00000040
+#define SPI_OP_IP_FIFO_NOT_EMPTY      0x00000020
+#define SPI_OP_OP_FIFO_NOT_EMPTY      0x00000010
+#define SPI_OP_STATE_VALID            0x00000004
+#define SPI_OP_STATE                  0x00000003
+
+#define SPI_OP_STATE_CLEAR_BITS       0x2
+enum msm_spi_state {
+	SPI_OP_STATE_RESET = 0x00000000,
+	SPI_OP_STATE_RUN   = 0x00000001,
+	SPI_OP_STATE_PAUSE = 0x00000003,
+};
+
+/* SPI_ERROR_FLAGS fields */
+#define SPI_ERR_OUTPUT_OVER_RUN_ERR   0x00000020
+#define SPI_ERR_INPUT_UNDER_RUN_ERR   0x00000010
+#define SPI_ERR_OUTPUT_UNDER_RUN_ERR  0x00000008
+#define SPI_ERR_INPUT_OVER_RUN_ERR    0x00000004
+#define SPI_ERR_CLK_OVER_RUN_ERR      0x00000002
+#define SPI_ERR_CLK_UNDER_RUN_ERR     0x00000001
+
+/* We don't allow transactions larger than 4K-64 or 64K-64 due to
+   mx_input/output_cnt register size */
+#define SPI_MAX_TRANSFERS             QSD_REG(0xFC0) QUP_REG(0xFC0)
+#define SPI_MAX_LEN                   (SPI_MAX_TRANSFERS * dd->bytes_per_word)
+
+#define SPI_NUM_CHIPSELECTS           4
+#define SPI_SUPPORTED_MODES  (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP)
+
+#define SPI_DELAY_THRESHOLD           1
+/* Default timeout is 10 milliseconds */
+#define SPI_DEFAULT_TIMEOUT           10
+/* 250 microseconds */
+#define SPI_TRYLOCK_DELAY             250
+
+/* Data Mover burst size */
+#define DM_BURST_SIZE                 16
+/* Data Mover commands should be aligned to 64 bit(8 bytes) */
+#define DM_BYTE_ALIGN                 8
+
+#define SPI_QUP_VERSION_NONE      0x0
+#define SPI_QUP_VERSION_BFAM      0x2
+
+static char const * const spi_rsrcs[] = {
+	"spi_clk",
+	"spi_miso",
+	"spi_mosi"
+};
+
+static char const * const spi_cs_rsrcs[] = {
+	"spi_cs",
+	"spi_cs1",
+	"spi_cs2",
+	"spi_cs3",
+};
+
+enum msm_spi_mode {
+	SPI_FIFO_MODE  = 0x0,  /* 00 */
+	SPI_BLOCK_MODE = 0x1,  /* 01 */
+	SPI_DMOV_MODE  = 0x2,  /* 10 */
+	SPI_BAM_MODE   = 0x3,  /* 11 */
+	SPI_MODE_NONE  = 0xFF, /* invalid value */
+};
+
+/* Structure for SPI CS GPIOs */
+struct spi_cs_gpio {
+	int  gpio_num;
+	bool valid;
+};
+
+/* Structures for Data Mover */
+struct spi_dmov_cmd {
+	dmov_box box;      /* data aligned to max(dm_burst_size, block_size)
+							   (<= fifo_size) */
+	dmov_s single_pad; /* data unaligned to max(dm_burst_size, block_size)
+			      padded to fit */
+	dma_addr_t cmd_ptr;
+};
+
+static struct pm_qos_request_list qos_req_list;
+
+#ifdef CONFIG_DEBUG_FS
+/* Used to create debugfs entries */
+static const struct {
+	const char *name;
+	mode_t mode;
+	int offset;
+} debugfs_spi_regs[] = {
+	{"config",                S_IRUGO | S_IWUSR, SPI_CONFIG},
+	{"io_control",            S_IRUGO | S_IWUSR, SPI_IO_CONTROL},
+	{"io_modes",              S_IRUGO | S_IWUSR, SPI_IO_MODES},
+	{"sw_reset",                        S_IWUSR, SPI_SW_RESET},
+	{"time_out_current",      S_IRUGO,           SPI_TIME_OUT_CURRENT},
+	{"mx_output_count",       S_IRUGO | S_IWUSR, SPI_MX_OUTPUT_COUNT},
+	{"mx_output_cnt_current", S_IRUGO,           SPI_MX_OUTPUT_CNT_CURRENT},
+	{"mx_input_count",        S_IRUGO | S_IWUSR, SPI_MX_INPUT_COUNT},
+	{"mx_input_cnt_current",  S_IRUGO,           SPI_MX_INPUT_CNT_CURRENT},
+	{"mx_read_count",         S_IRUGO | S_IWUSR, SPI_MX_READ_COUNT},
+	{"mx_read_cnt_current",   S_IRUGO,           SPI_MX_READ_CNT_CURRENT},
+	{"operational",           S_IRUGO | S_IWUSR, SPI_OPERATIONAL},
+	{"error_flags",           S_IRUGO | S_IWUSR, SPI_ERROR_FLAGS},
+	{"error_flags_en",        S_IRUGO | S_IWUSR, SPI_ERROR_FLAGS_EN},
+	{"deassert_wait",         S_IRUGO | S_IWUSR, SPI_DEASSERT_WAIT},
+	{"output_debug",          S_IRUGO,           SPI_OUTPUT_DEBUG},
+	{"input_debug",           S_IRUGO,           SPI_INPUT_DEBUG},
+	{"test_ctrl",             S_IRUGO | S_IWUSR, SPI_TEST_CTRL},
+	{"output_fifo",                     S_IWUSR, SPI_OUTPUT_FIFO},
+	{"input_fifo" ,           S_IRUSR,           SPI_INPUT_FIFO},
+	{"spi_state",             S_IRUGO | S_IWUSR, SPI_STATE},
+#if defined(CONFIG_SPI_QSD) || defined(CONFIG_SPI_QSD_MODULE)
+	{"fifo_word_cnt",         S_IRUGO,           SPI_FIFO_WORD_CNT},
+#else
+	{"qup_config",            S_IRUGO | S_IWUSR, QUP_CONFIG},
+	{"qup_error_flags",       S_IRUGO | S_IWUSR, QUP_ERROR_FLAGS},
+	{"qup_error_flags_en",    S_IRUGO | S_IWUSR, QUP_ERROR_FLAGS_EN},
+	{"mx_write_cnt",          S_IRUGO | S_IWUSR, QUP_MX_WRITE_COUNT},
+	{"mx_write_cnt_current",  S_IRUGO,           QUP_MX_WRITE_CNT_CURRENT},
+	{"output_fifo_word_cnt",  S_IRUGO,           SPI_OUTPUT_FIFO_WORD_CNT},
+	{"input_fifo_word_cnt",   S_IRUGO,           SPI_INPUT_FIFO_WORD_CNT},
+#endif
+};
+#endif
+
+struct msm_spi {
+	u8                      *read_buf;
+	const u8                *write_buf;
+	void __iomem            *base;
+	struct device           *dev;
+	spinlock_t               queue_lock;
+	struct mutex             core_lock;
+	struct list_head         queue;
+	struct workqueue_struct *workqueue;
+	struct work_struct       work_data;
+	struct spi_message      *cur_msg;
+	struct spi_transfer     *cur_transfer;
+	struct completion        transfer_complete;
+	struct clk              *clk;
+	struct clk              *pclk;
+	unsigned long            mem_phys_addr;
+	size_t                   mem_size;
+	int                      input_fifo_size;
+	int                      output_fifo_size;
+	u32                      rx_bytes_remaining;
+	u32                      tx_bytes_remaining;
+	u32                      clock_speed;
+	int                      irq_in;
+	int                      read_xfr_cnt;
+	int                      write_xfr_cnt;
+	int                      write_len;
+	int                      read_len;
+#if defined(CONFIG_SPI_QSD) || defined(CONFIG_SPI_QSD_MODULE)
+	int                      irq_out;
+	int                      irq_err;
+#endif
+	int                      bytes_per_word;
+	bool                     suspended;
+	bool                     transfer_pending;
+	wait_queue_head_t        continue_suspend;
+	/* DMA data */
+	enum msm_spi_mode        mode;
+	bool                     use_dma;
+	int                      tx_dma_chan;
+	int                      tx_dma_crci;
+	int                      rx_dma_chan;
+	int                      rx_dma_crci;
+	/* Data Mover Commands */
+	struct spi_dmov_cmd      *tx_dmov_cmd;
+	struct spi_dmov_cmd      *rx_dmov_cmd;
+	/* Physical address of the tx dmov box command */
+	dma_addr_t               tx_dmov_cmd_dma;
+	dma_addr_t               rx_dmov_cmd_dma;
+	struct msm_dmov_cmd      tx_hdr;
+	struct msm_dmov_cmd      rx_hdr;
+	int                      input_block_size;
+	int                      output_block_size;
+	int                      burst_size;
+	atomic_t                 rx_irq_called;
+	/* Used to pad messages unaligned to block size */
+	u8                       *tx_padding;
+	dma_addr_t               tx_padding_dma;
+	u8                       *rx_padding;
+	dma_addr_t               rx_padding_dma;
+	u32                      unaligned_len;
+	/* DMA statistics */
+	int                      stat_dmov_tx_err;
+	int                      stat_dmov_rx_err;
+	int                      stat_rx;
+	int                      stat_dmov_rx;
+	int                      stat_tx;
+	int                      stat_dmov_tx;
+#ifdef CONFIG_DEBUG_FS
+	struct dentry *dent_spi;
+	struct dentry *debugfs_spi_regs[ARRAY_SIZE(debugfs_spi_regs)];
+#endif
+	struct msm_spi_platform_data *pdata; /* Platform data */
+	/* Remote Spinlock Data */
+	bool                     use_rlock;
+	remote_mutex_t           r_lock;
+	uint32_t                 pm_lat;
+	/* When set indicates multiple transfers in a single message */
+	bool                     multi_xfr;
+	bool                     done;
+	u32                      cur_msg_len;
+	/* Used in FIFO mode to keep track of the transfer being processed */
+	struct spi_transfer     *cur_tx_transfer;
+	struct spi_transfer     *cur_rx_transfer;
+	/* Temporary buffer used for WR-WR or WR-RD transfers */
+	u8                      *temp_buf;
+	/* GPIO pin numbers for SPI clk, miso and mosi */
+	int                      spi_gpios[ARRAY_SIZE(spi_rsrcs)];
+	/* SPI CS GPIOs for each slave */
+	struct spi_cs_gpio       cs_gpios[ARRAY_SIZE(spi_cs_rsrcs)];
+	int                      qup_ver;
+};
+
+/* Forward declaration */
+static irqreturn_t msm_spi_input_irq(int irq, void *dev_id);
+static irqreturn_t msm_spi_output_irq(int irq, void *dev_id);
+static irqreturn_t msm_spi_error_irq(int irq, void *dev_id);
+static inline int msm_spi_set_state(struct msm_spi *dd,
+				    enum msm_spi_state state);
+static void msm_spi_write_word_to_fifo(struct msm_spi *dd);
+static inline void msm_spi_write_rmn_to_fifo(struct msm_spi *dd);
+static irqreturn_t msm_spi_qup_irq(int irq, void *dev_id);
+
+#if defined(CONFIG_SPI_QSD) || defined(CONFIG_SPI_QSD_MODULE)
+static inline void msm_spi_disable_irqs(struct msm_spi *dd)
+{
+	disable_irq(dd->irq_in);
+	disable_irq(dd->irq_out);
+	disable_irq(dd->irq_err);
+}
+
+static inline void msm_spi_enable_irqs(struct msm_spi *dd)
+{
+	enable_irq(dd->irq_in);
+	enable_irq(dd->irq_out);
+	enable_irq(dd->irq_err);
+}
+
+static inline int msm_spi_request_irq(struct msm_spi *dd,
+				struct platform_device *pdev,
+				struct spi_master *master)
+{
+	int rc;
+
+	dd->irq_in  = platform_get_irq(pdev, 0);
+	dd->irq_out = platform_get_irq(pdev, 1);
+	dd->irq_err = platform_get_irq(pdev, 2);
+	if ((dd->irq_in < 0) || (dd->irq_out < 0) || (dd->irq_err < 0))
+		return -EINVAL;
+
+	rc = devm_request_irq(dd->dev, dd->irq_in, msm_spi_input_irq,
+		IRQF_TRIGGER_RISING, pdev->name, dd);
+	if (rc)
+		goto error_irq;
+
+	rc = devm_request_irq(dd->dev, dd->irq_out, msm_spi_output_irq,
+		IRQF_TRIGGER_RISING, pdev->name, dd);
+	if (rc)
+		goto error_irq;
+
+	rc = devm_request_irq(dd->dev, dd->irq_err, msm_spi_error_irq,
+		IRQF_TRIGGER_RISING, pdev->name, master);
+	if (rc)
+		goto error_irq;
+
+error_irq:
+	return rc;
+}
+
+static inline void msm_spi_get_clk_err(struct msm_spi *dd, u32 *spi_err) {}
+static inline void msm_spi_ack_clk_err(struct msm_spi *dd) {}
+static inline void msm_spi_set_qup_config(struct msm_spi *dd, int bpw) {}
+
+static inline int msm_spi_prepare_for_write(struct msm_spi *dd) { return 0; }
+static inline void msm_spi_start_write(struct msm_spi *dd, u32 read_count)
+{
+	msm_spi_write_word_to_fifo(dd);
+}
+static inline void msm_spi_set_write_count(struct msm_spi *dd, int val) {}
+
+static inline void msm_spi_complete(struct msm_spi *dd)
+{
+	complete(&dd->transfer_complete);
+}
+
+static inline void msm_spi_enable_error_flags(struct msm_spi *dd)
+{
+	writel_relaxed(0x0000007B, dd->base + SPI_ERROR_FLAGS_EN);
+}
+
+static inline void msm_spi_clear_error_flags(struct msm_spi *dd)
+{
+	writel_relaxed(0x0000007F, dd->base + SPI_ERROR_FLAGS);
+}
+
+#else
+/* In QUP the same interrupt line is used for input, output and error*/
+static inline int msm_spi_request_irq(struct msm_spi *dd,
+				struct platform_device *pdev,
+				struct spi_master *master)
+{
+	dd->irq_in  = platform_get_irq(pdev, 0);
+	if (dd->irq_in < 0)
+		return -EINVAL;
+
+	return devm_request_irq(dd->dev, dd->irq_in, msm_spi_qup_irq,
+		IRQF_TRIGGER_HIGH, pdev->name, dd);
+}
+
+static inline void msm_spi_disable_irqs(struct msm_spi *dd)
+{
+	disable_irq(dd->irq_in);
+}
+
+static inline void msm_spi_enable_irqs(struct msm_spi *dd)
+{
+	enable_irq(dd->irq_in);
+}
+
+static inline void msm_spi_get_clk_err(struct msm_spi *dd, u32 *spi_err)
+{
+	*spi_err = readl_relaxed(dd->base + QUP_ERROR_FLAGS);
+}
+
+static inline void msm_spi_ack_clk_err(struct msm_spi *dd)
+{
+	writel_relaxed(QUP_ERR_MASK, dd->base + QUP_ERROR_FLAGS);
+}
+
+static inline void msm_spi_add_configs(struct msm_spi *dd, u32 *config, int n);
+
+/* QUP has no_input, no_output, and N bits at QUP_CONFIG */
+static inline void msm_spi_set_qup_config(struct msm_spi *dd, int bpw)
+{
+	u32 qup_config = readl_relaxed(dd->base + QUP_CONFIG);
+
+	msm_spi_add_configs(dd, &qup_config, bpw-1);
+	writel_relaxed(qup_config | QUP_CONFIG_SPI_MODE,
+		       dd->base + QUP_CONFIG);
+}
+
+static inline int msm_spi_prepare_for_write(struct msm_spi *dd)
+{
+	if (msm_spi_set_state(dd, SPI_OP_STATE_RUN))
+		return -EINVAL;
+	if (msm_spi_set_state(dd, SPI_OP_STATE_PAUSE))
+		return -EINVAL;
+	return 0;
+}
+
+static inline void msm_spi_start_write(struct msm_spi *dd, u32 read_count)
+{
+	if (read_count <= dd->input_fifo_size)
+		msm_spi_write_rmn_to_fifo(dd);
+	else
+		msm_spi_write_word_to_fifo(dd);
+}
+
+static inline void msm_spi_set_write_count(struct msm_spi *dd, int val)
+{
+	writel_relaxed(val, dd->base + QUP_MX_WRITE_COUNT);
+}
+
+static inline void msm_spi_complete(struct msm_spi *dd)
+{
+	dd->done = 1;
+}
+
+static inline void msm_spi_enable_error_flags(struct msm_spi *dd)
+{
+	writel_relaxed(0x00000078, dd->base + SPI_ERROR_FLAGS_EN);
+}
+
+static inline void msm_spi_clear_error_flags(struct msm_spi *dd)
+{
+	writel_relaxed(0x0000007C, dd->base + SPI_ERROR_FLAGS);
+}
+
+#endif
+#endif
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/thermal/msm8960_tsens.c b/drivers/thermal/msm8960_tsens.c
index 63d8666..a616ffc 100644
--- a/drivers/thermal/msm8960_tsens.c
+++ b/drivers/thermal/msm8960_tsens.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
@@ -81,7 +81,7 @@
 /* Initial temperature threshold values */
 #define TSENS_LOWER_LIMIT_TH				0x50
 #define TSENS_UPPER_LIMIT_TH				0xdf
-#define TSENS_MIN_LIMIT_TH				0x38
+#define TSENS_MIN_LIMIT_TH				0x0
 #define TSENS_MAX_LIMIT_TH				0xff
 
 #define TSENS_S0_STATUS_ADDR			(MSM_CLK_CTL_BASE + 0x00003628)
@@ -424,6 +424,15 @@
 	return tsens_tz_get_trip_temp(thermal, TSENS_TRIP_STAGE3, temp);
 }
 
+static int tsens_tz_notify(struct thermal_zone_device *thermal,
+				int count, enum thermal_trip_type type)
+{
+	/* TSENS driver does not shutdown the device.
+	   All Thermal notification are sent to the
+	   thermal daemon to take appropriate action */
+	return 1;
+}
+
 static int tsens_tz_set_trip_temp(struct thermal_zone_device *thermal,
 				   int trip, long temp)
 {
@@ -519,6 +528,7 @@
 	.get_trip_temp = tsens_tz_get_trip_temp,
 	.set_trip_temp = tsens_tz_set_trip_temp,
 	.get_crit_temp = tsens_tz_get_crit_temp,
+	.notify = tsens_tz_notify,
 };
 
 static void notify_uspace_tsens_fn(struct work_struct *work)
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 94ed950..97e7aa4 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -594,6 +594,24 @@
 	default USB_GADGET
 	select USB_GADGET_SELECTED
 
+config USB_GADGET_CI13XXX_MSM_HSIC
+	boolean "MIPS HSIC CI13xxx for MSM"
+	depends on ARCH_MSM
+	select USB_GADGET_DUALSPEED
+	help
+	  MSM SoC has chipidea USB controller.  This driver uses
+	  ci13xxx_udc core. Support USB-HSIC core.
+
+	  Say "y" to link the driver statically, or "m" to build a
+	  dynamically linked module called "ci13xxx_msm_hsic" and force all
+	  gadget drivers to also be dynamically linked.
+
+config USB_CI13XXX_MSM_HSIC
+	tristate
+	depends on USB_GADGET_CI13XXX_MSM_HSIC
+	default USB_GADGET
+	select USB_GADGET_SELECTED
+
 #
 # LAST -- dummy/emulated controller
 #
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 064960c..141f649 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -27,6 +27,7 @@
 obj-$(CONFIG_USB_EG20T)		+= pch_udc.o
 obj-$(CONFIG_USB_PXA_U2O)	+= mv_udc.o
 mv_udc-y			:= mv_udc_core.o mv_udc_phy.o
+obj-$(CONFIG_USB_CI13XXX_MSM_HSIC)	+= ci13xxx_msm_hsic.o
 obj-$(CONFIG_USB_CI13XXX_MSM)	+= ci13xxx_msm.o
 obj-$(CONFIG_USB_FUSB300)	+= fusb300_udc.o
 obj-$(CONFIG_USB_MSM_72K)	+= msm72k_udc.o
diff --git a/drivers/usb/gadget/ci13xxx_msm_hsic.c b/drivers/usb/gadget/ci13xxx_msm_hsic.c
new file mode 100644
index 0000000..135c84d
--- /dev/null
+++ b/drivers/usb/gadget/ci13xxx_msm_hsic.c
@@ -0,0 +1,484 @@
+/* Copyright (c) 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
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/wakelock.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/usb.h>
+
+#include <linux/usb/gadget.h>
+#include <linux/usb/msm_hsusb_hw.h>
+#include <linux/usb/msm_hsusb.h>
+
+#include <mach/clk.h>
+#include <mach/msm_iomap.h>
+#include <mach/msm_xo.h>
+
+#include "ci13xxx_udc.c"
+
+#define MSM_USB_BASE	(mhsic->regs)
+
+#define ULPI_IO_TIMEOUT_USEC	(10 * 1000)
+#define USB_PHY_VDD_DIG_VOL_MIN		1045000 /* uV */
+#define USB_PHY_VDD_DIG_VOL_MAX		1320000 /* uV */
+#define USB_PHY_VDD_DIG_LOAD		49360	/* uA */
+#define LINK_RESET_TIMEOUT_USEC		(250 * 1000)
+#define HSIC_CFG_REG 0x30
+#define HSIC_IO_CAL_PER_REG 0x33
+#define HSIC_DBG1_REG 0x38
+
+struct msm_hsic_per *the_mhsic;
+
+struct msm_hsic_per {
+	struct device		*dev;
+	struct clk			*iface_clk;
+	struct clk			*core_clk;
+	struct clk			*alt_core_clk;
+	struct clk			*phy_clk;
+	struct clk			*cal_clk;
+	struct regulator	*hsic_vddcx;
+	bool				async_int;
+	void __iomem		*regs;
+	int					irq;
+};
+
+static int msm_hsic_init_vddcx(struct msm_hsic_per *mhsic, int init)
+{
+	int ret = 0;
+
+	if (!init)
+		goto disable_reg;
+
+	mhsic->hsic_vddcx = regulator_get(mhsic->dev, "HSIC_VDDCX");
+	if (IS_ERR(mhsic->hsic_vddcx)) {
+		dev_err(mhsic->dev, "unable to get hsic vddcx\n");
+		return PTR_ERR(mhsic->hsic_vddcx);
+	}
+
+	ret = regulator_set_voltage(mhsic->hsic_vddcx,
+			USB_PHY_VDD_DIG_VOL_MIN,
+			USB_PHY_VDD_DIG_VOL_MAX);
+	if (ret) {
+		dev_err(mhsic->dev, "unable to set the voltage"
+				"for hsic vddcx\n");
+		goto reg_set_voltage_err;
+	}
+
+	ret = regulator_set_optimum_mode(mhsic->hsic_vddcx,
+				USB_PHY_VDD_DIG_LOAD);
+	if (ret < 0) {
+		pr_err("%s: Unable to set optimum mode of the regulator:"
+					"VDDCX\n", __func__);
+		goto reg_optimum_mode_err;
+	}
+
+	ret = regulator_enable(mhsic->hsic_vddcx);
+	if (ret) {
+		dev_err(mhsic->dev, "unable to enable hsic vddcx\n");
+		goto reg_enable_err;
+	}
+
+	return 0;
+
+disable_reg:
+	regulator_disable(mhsic->hsic_vddcx);
+reg_enable_err:
+	regulator_set_optimum_mode(mhsic->hsic_vddcx, 0);
+reg_optimum_mode_err:
+	regulator_set_voltage(mhsic->hsic_vddcx, 0,
+				USB_PHY_VDD_DIG_VOL_MIN);
+reg_set_voltage_err:
+	regulator_put(mhsic->hsic_vddcx);
+
+	return ret;
+
+}
+
+static int ulpi_write(struct msm_hsic_per *mhsic, u32 val, u32 reg)
+{
+	int cnt = 0;
+
+	/* initiate write operation */
+	writel_relaxed(ULPI_RUN | ULPI_WRITE |
+	       ULPI_ADDR(reg) | ULPI_DATA(val),
+	       USB_ULPI_VIEWPORT);
+
+	/* wait for completion */
+	while (cnt < ULPI_IO_TIMEOUT_USEC) {
+		if (!(readl_relaxed(USB_ULPI_VIEWPORT) & ULPI_RUN))
+			break;
+		udelay(1);
+		cnt++;
+	}
+
+	if (cnt >= ULPI_IO_TIMEOUT_USEC) {
+		dev_err(mhsic->dev, "ulpi_write: timeout\n");
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+static int msm_hsic_phy_clk_reset(struct msm_hsic_per *mhsic)
+{
+	int ret;
+
+	ret = clk_reset(mhsic->core_clk, CLK_RESET_ASSERT);
+	if (ret) {
+		clk_disable(mhsic->alt_core_clk);
+		dev_err(mhsic->dev, "usb phy clk assert failed\n");
+		return ret;
+	}
+	usleep_range(10000, 12000);
+	clk_disable(mhsic->alt_core_clk);
+
+	ret = clk_reset(mhsic->core_clk, CLK_RESET_DEASSERT);
+	if (ret)
+		dev_err(mhsic->dev, "usb phy clk deassert failed\n");
+
+	return ret;
+}
+
+static int msm_hsic_phy_reset(struct msm_hsic_per *mhsic)
+{
+	u32 val;
+	int ret;
+
+	ret = msm_hsic_phy_clk_reset(mhsic);
+	if (ret)
+		return ret;
+
+	val = readl_relaxed(USB_PORTSC) & ~PORTSC_PTS_MASK;
+	writel_relaxed(val | PORTSC_PTS_ULPI, USB_PORTSC);
+
+	/*
+	 * Ensure that RESET operation is completed before
+	 * turning off clock.
+	 */
+	mb();
+	dev_dbg(mhsic->dev, "phy_reset: success\n");
+
+	return 0;
+}
+
+static int msm_hsic_enable_clocks(struct platform_device *pdev,
+				struct msm_hsic_per *mhsic, bool enable)
+{
+	int ret = 0;
+
+	if (!enable)
+		goto put_clocks;
+
+	mhsic->iface_clk = clk_get(&pdev->dev, "iface_clk");
+	if (IS_ERR(mhsic->iface_clk)) {
+		dev_err(mhsic->dev, "failed to get iface_clk\n");
+		ret = PTR_ERR(mhsic->iface_clk);
+		goto put_iface_clk;
+	}
+
+	mhsic->core_clk = clk_get(&pdev->dev, "core_clk");
+	if (IS_ERR(mhsic->core_clk)) {
+		dev_err(mhsic->dev, "failed to get core_clk\n");
+		ret = PTR_ERR(mhsic->core_clk);
+		goto put_core_clk;
+	}
+
+	mhsic->phy_clk = clk_get(&pdev->dev, "phy_clk");
+	if (IS_ERR(mhsic->phy_clk)) {
+		dev_err(mhsic->dev, "failed to get phy_clk\n");
+		ret = PTR_ERR(mhsic->phy_clk);
+		goto put_phy_clk;
+	}
+
+	mhsic->alt_core_clk = clk_get(&pdev->dev, "alt_core_clk");
+	if (IS_ERR(mhsic->alt_core_clk)) {
+		dev_err(mhsic->dev, "failed to get alt_core_clk\n");
+		ret = PTR_ERR(mhsic->alt_core_clk);
+		goto put_alt_core_clk;
+	}
+
+	mhsic->cal_clk = clk_get(&pdev->dev, "cal_clk");
+	if (IS_ERR(mhsic->cal_clk)) {
+		dev_err(mhsic->dev, "failed to get cal_clk\n");
+		ret = PTR_ERR(mhsic->cal_clk);
+		goto put_cal_clk;
+	}
+
+	clk_enable(mhsic->iface_clk);
+	clk_enable(mhsic->core_clk);
+	clk_enable(mhsic->phy_clk);
+	clk_enable(mhsic->alt_core_clk);
+	clk_enable(mhsic->cal_clk);
+
+	return 0;
+
+put_clocks:
+	clk_disable(mhsic->iface_clk);
+	clk_disable(mhsic->core_clk);
+	clk_disable(mhsic->phy_clk);
+	clk_disable(mhsic->alt_core_clk);
+	clk_disable(mhsic->cal_clk);
+put_cal_clk:
+	clk_put(mhsic->cal_clk);
+put_alt_core_clk:
+	clk_put(mhsic->alt_core_clk);
+put_phy_clk:
+	clk_put(mhsic->phy_clk);
+put_core_clk:
+	clk_put(mhsic->core_clk);
+put_iface_clk:
+	clk_put(mhsic->iface_clk);
+
+	return ret;
+}
+
+static int msm_hsic_reset(struct msm_hsic_per *mhsic)
+{
+	int cnt = 0;
+	int ret;
+
+	ret = msm_hsic_phy_reset(mhsic);
+	if (ret) {
+		dev_err(mhsic->dev, "phy_reset failed\n");
+		return ret;
+	}
+
+	writel_relaxed(USBCMD_RESET, USB_USBCMD);
+	while (cnt < LINK_RESET_TIMEOUT_USEC) {
+		if (!(readl_relaxed(USB_USBCMD) & USBCMD_RESET))
+			break;
+		udelay(1);
+		cnt++;
+	}
+	if (cnt >= LINK_RESET_TIMEOUT_USEC)
+		return -ETIMEDOUT;
+
+	/* Reset PORTSC and select ULPI phy */
+	writel_relaxed(0x80000000, USB_PORTSC);
+	return 0;
+}
+
+static void msm_hsic_start(void)
+{
+	int ret;
+
+	/* programmable length of connect signaling (33.2ns) */
+	ret = ulpi_write(the_mhsic, 3, HSIC_DBG1_REG);
+	if (ret) {
+		pr_err("%s: Unable to program length of connect signaling\n",
+			    __func__);
+	}
+
+	/*set periodic calibration interval to ~2.048sec in HSIC_IO_CAL_REG */
+	ret = ulpi_write(the_mhsic, 0xFF, HSIC_IO_CAL_PER_REG);
+
+	if (ret) {
+		pr_err("%s: Unable to set periodic calibration interval\n",
+			    __func__);
+	}
+
+	/* Enable periodic IO calibration in HSIC_CFG register */
+	ret = ulpi_write(the_mhsic, 0xE9, HSIC_CFG_REG);
+	if (ret) {
+		pr_err("%s: Unable to enable periodic IO calibration\n",
+			    __func__);
+	}
+}
+
+/**
+ * Dummy match function - will be called only for HSIC msm
+ * device (msm_device_gadget_hsic_peripheral).
+ */
+static inline int __match(struct device *dev, void *data) { return 1; }
+
+static void msm_hsic_connect_peripheral(struct device *msm_udc_dev)
+{
+	struct device *dev;
+	struct usb_gadget *gadget;
+
+	dev = device_find_child(msm_udc_dev, NULL, __match);
+	gadget = dev_to_usb_gadget(dev);
+	usb_gadget_vbus_connect(gadget);
+}
+
+static irqreturn_t msm_udc_hsic_irq(int irq, void *data)
+{
+	return udc_irq();
+}
+
+static void ci13xxx_msm_hsic_notify_event(struct ci13xxx *udc, unsigned event)
+{
+	struct device *dev = udc->gadget.dev.parent;
+	struct msm_hsic_per *mhsic = the_mhsic;
+
+	switch (event) {
+	case CI13XXX_CONTROLLER_RESET_EVENT:
+		dev_dbg(dev, "CI13XXX_CONTROLLER_RESET_EVENT received\n");
+		writel_relaxed(0, USB_AHBBURST);
+		writel_relaxed(0, USB_AHBMODE);
+		break;
+	case CI13XXX_CONTROLLER_CONNECT_EVENT:
+		dev_dbg(dev, "CI13XXX_CONTROLLER_CONNECT_EVENT received\n");
+		msm_hsic_start();
+		break;
+	default:
+		dev_dbg(dev, "unknown ci13xxx_udc event\n");
+		break;
+	}
+}
+
+static struct ci13xxx_udc_driver ci13xxx_msm_udc_hsic_driver = {
+	.name			= "ci13xxx_msm_hsic",
+	.flags			= CI13XXX_REGS_SHARED |
+				  CI13XXX_PULLUP_ON_VBUS |
+				  CI13XXX_DISABLE_STREAMING |
+				  CI13XXX_ZERO_ITC,
+
+	.notify_event		= ci13xxx_msm_hsic_notify_event,
+};
+
+static int __devinit msm_hsic_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct msm_hsic_per *mhsic;
+	int ret = 0;
+
+	dev_dbg(&pdev->dev, "msm-hsic probe\n");
+
+	mhsic = kzalloc(sizeof(struct msm_hsic_per), GFP_KERNEL);
+	if (!mhsic) {
+		dev_err(&pdev->dev, "unable to allocate msm_hsic\n");
+		return -ENOMEM;
+	}
+	the_mhsic = mhsic;
+	platform_set_drvdata(pdev, mhsic);
+	mhsic->dev = &pdev->dev;
+
+	mhsic->irq = platform_get_irq(pdev, 0);
+	if (mhsic->irq < 0) {
+		dev_err(&pdev->dev, "Unable to get IRQ resource\n");
+		ret = mhsic->irq;
+		goto error;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "Unable to get memory resource\n");
+		ret = -ENODEV;
+		goto error;
+	}
+	mhsic->regs = ioremap(res->start, resource_size(res));
+	if (!mhsic->regs) {
+		dev_err(&pdev->dev, "ioremap failed\n");
+		ret = -ENOMEM;
+		goto unmap;
+	}
+	dev_info(&pdev->dev, "HSIC Peripheral regs = %p\n", mhsic->regs);
+
+	ret = msm_hsic_enable_clocks(pdev, mhsic, true);
+
+	if (ret) {
+		dev_err(&pdev->dev, "msm_hsic_enable_clocks failed\n");
+		ret = -ENODEV;
+		goto deinit_clocks;
+	}
+	ret = msm_hsic_init_vddcx(mhsic, 1);
+	if (ret) {
+		dev_err(&pdev->dev, "unable to initialize VDDCX\n");
+		ret = -ENODEV;
+		goto deinit_vddcx;
+	}
+
+	ret = msm_hsic_reset(mhsic);
+	if (ret) {
+		dev_err(&pdev->dev, "msm_hsic_reset failed\n");
+		ret = -ENODEV;
+		goto deinit_vddcx;
+	}
+
+	ret = udc_probe(&ci13xxx_msm_udc_hsic_driver, &pdev->dev, mhsic->regs);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "udc_probe failed\n");
+		ret = -ENODEV;
+		goto deinit_vddcx;
+	}
+
+	msm_hsic_connect_peripheral(&pdev->dev);
+
+	ret = request_irq(mhsic->irq, msm_udc_hsic_irq,
+					  IRQF_SHARED, pdev->name, pdev);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "request_irq failed\n");
+		ret = -ENODEV;
+		goto udc_remove;
+	}
+
+	pm_runtime_no_callbacks(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+
+	return 0;
+udc_remove:
+	udc_remove();
+deinit_vddcx:
+	msm_hsic_init_vddcx(mhsic, 0);
+deinit_clocks:
+	msm_hsic_enable_clocks(pdev, mhsic, 0);
+unmap:
+	iounmap(mhsic->regs);
+error:
+	kfree(mhsic);
+	return ret;
+}
+
+static int __devexit hsic_msm_remove(struct platform_device *pdev)
+{
+	struct msm_hsic_per *mhsic = platform_get_drvdata(pdev);
+
+	device_init_wakeup(&pdev->dev, 0);
+	msm_hsic_init_vddcx(mhsic, 0);
+	msm_hsic_enable_clocks(pdev, mhsic, 0);
+	udc_remove();
+	iounmap(mhsic->regs);
+	kfree(mhsic);
+
+	return 0;
+}
+static struct platform_driver msm_hsic_peripheral_driver = {
+	.probe	= msm_hsic_probe,
+	.remove	= __devexit_p(hsic_msm_remove),
+	.driver = {
+		.name = "msm_hsic_peripheral",
+	},
+};
+
+static int __init msm_hsic_peripheral_init(void)
+{
+	return platform_driver_probe(&msm_hsic_peripheral_driver,
+								msm_hsic_probe);
+}
+
+static void __exit msm_hsic_peripheral_exit(void)
+{
+	platform_driver_unregister(&msm_hsic_peripheral_driver);
+}
+
+module_init(msm_hsic_peripheral_init);
+module_exit(msm_hsic_peripheral_exit);
+
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index 703494a..35327cc 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -2816,8 +2816,12 @@
 	}
 	spin_unlock_irqrestore(udc->lock, flags);
 
-	if (is_active)
+	if (is_active) {
 		hw_device_state(udc->ep0out.qh.dma);
+		if (udc->udc_driver->notify_event)
+			udc->udc_driver->notify_event(udc,
+				CI13XXX_CONTROLLER_CONNECT_EVENT);
+	}
 	else
 		hw_device_state(0);
 
diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h
index 35b0712..fce611a 100644
--- a/drivers/usb/gadget/ci13xxx_udc.h
+++ b/drivers/usb/gadget/ci13xxx_udc.h
@@ -127,6 +127,7 @@
 #define CI13XXX_ZERO_ITC		BIT(4)
 
 #define CI13XXX_CONTROLLER_RESET_EVENT		0
+#define CI13XXX_CONTROLLER_CONNECT_EVENT	1
 	void	(*notify_event) (struct ci13xxx *udc, unsigned event);
 };
 
@@ -233,7 +234,10 @@
 			   "[%s] " format "\n", __func__, ## args); \
 } while (0)
 
+#ifndef err
 #define err(format, args...)    ci13xxx_printk(KERN_ERR, format, ## args)
+#endif
+
 #define warn(format, args...)   ci13xxx_printk(KERN_WARNING, format, ## args)
 #define info(format, args...)   ci13xxx_printk(KERN_INFO, format, ## args)
 
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/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
index 05692bb..da312d4 100644
--- a/drivers/usb/gadget/gadget_chips.h
+++ b/drivers/usb/gadget/gadget_chips.h
@@ -160,6 +160,13 @@
 #define gadget_is_ci13xxx_msm(g)	0
 #endif
 
+#ifdef CONFIG_USB_GADGET_CI13XXX_MSM_HSIC
+#define gadget_is_ci13xxx_msm_hsic(g)	\
+		(!strncmp("ci13xxx_msm_hsic", (g)->name, 16))
+#else
+#define gadget_is_ci13xxx_msm_hsic(g)	0
+#endif
+
 #ifdef CONFIG_USB_GADGET_RENESAS_USBHS
 #define	gadget_is_renesas_usbhs(g) (!strcmp("renesas_usbhs_udc", (g)->name))
 #else
@@ -231,6 +238,8 @@
 		return 0x30;
 	else if (gadget_is_msm72k(gadget))
 		return 0x31;
+	else if (gadget_is_ci13xxx_msm_hsic(gadget))
+		return 0x32;
 
 	return -ENOENT;
 }
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 56559bf..ec9ac24 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -38,6 +38,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/mfd/pm8xxx/pm8921-charger.h>
 #include <linux/pm_qos_params.h>
+#include <linux/power_supply.h>
 
 #include <mach/clk.h>
 #include <mach/msm_xo.h>
@@ -838,6 +839,35 @@
 }
 #endif
 
+static int msm_otg_notify_power_supply(struct msm_otg *motg, unsigned mA)
+{
+	struct power_supply *psy;
+
+	psy = power_supply_get_by_name("usb");
+	if (!psy)
+		goto psy_not_supported;
+
+	if (motg->cur_power == 0 && mA > 0) {
+		/* Enable charging */
+		if (power_supply_set_online(psy, true))
+			goto psy_not_supported;
+	} else if (motg->cur_power > 0 && mA == 0) {
+		/* Disable charging */
+		if (power_supply_set_online(psy, false))
+			goto psy_not_supported;
+		return 0;
+	}
+	/* Set max current limit */
+	if (power_supply_set_current_limit(psy, 1000*mA))
+		goto psy_not_supported;
+
+	return 0;
+
+psy_not_supported:
+	dev_dbg(motg->otg.dev, "Power Supply doesn't support USB charger\n");
+	return -ENXIO;
+}
+
 static void msm_otg_notify_charger(struct msm_otg *motg, unsigned mA)
 {
 	if ((motg->chg_type == USB_ACA_DOCK_CHARGER ||
@@ -851,7 +881,14 @@
 		return;
 
 	dev_info(motg->otg.dev, "Avail curr from USB = %u\n", mA);
-	pm8921_charger_vbus_draw(mA);
+
+	/*
+	 *  Use Power Supply API if supported, otherwise fallback
+	 *  to legacy pm8921 API.
+	 */
+	if (msm_otg_notify_power_supply(motg, mA))
+		pm8921_charger_vbus_draw(mA);
+
 	motg->cur_power = mA;
 }
 
@@ -1676,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.
@@ -1693,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;
@@ -2474,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,
@@ -2508,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/mdp.c b/drivers/video/msm/mdp.c
index 7c7ece2..db60546 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -1642,8 +1642,8 @@
 			if (mdp_version < 0x04030303) {
 				pr_err("%s: writeback panel not supprted\n",
 					 __func__);
-				rc = -ENODEV;
-				goto mdp_probe_err;
+				platform_device_put(msm_fb_dev);
+				return -ENODEV;
 			}
 			pdata->on = mdp4_overlay_writeback_on;
 			pdata->off = mdp4_overlay_writeback_off;
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_core.h b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h
index e9c5193..a0d30b6 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_core.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
@@ -63,6 +63,7 @@
 #define DDL_FW_AUX_HOST_CMD_SPACE_SIZE         (DDL_KILO_BYTE(8))
 #define DDL_FW_INST_GLOBAL_CONTEXT_SPACE_SIZE  (DDL_KILO_BYTE(800))
 #define DDL_FW_H264DEC_CONTEXT_SPACE_SIZE      (DDL_KILO_BYTE(800))
+#define DDL_FW_H264ENC_CONTEXT_SPACE_SIZE      (DDL_KILO_BYTE(20))
 #define DDL_FW_OTHER_CONTEXT_SPACE_SIZE        (DDL_KILO_BYTE(10))
 
 #define VCD_DEC_CPB_SIZE         (DDL_KILO_BYTE(512))
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
index b3790a5..d54c01e 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.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
@@ -751,6 +751,7 @@
 		sz_cur_c = sz_dpb_c;
 	} else
 		status = VCD_ERR_NOT_SUPPORTED;
+	sz_context = DDL_FW_OTHER_CONTEXT_SPACE_SIZE;
 	if (!status) {
 		sz_strm = DDL_ALIGN(ddl_get_yuv_buf_size(width, height,
 			DDL_YUV_BUF_TYPE_LINEAR) + ddl_get_yuv_buf_size(width,
@@ -768,6 +769,7 @@
 		} else if (codec == VCD_CODEC_H264) {
 			sz_md = DDL_ALIGN(mb_x * 48, DDL_KILO_BYTE(2));
 			sz_pred = DDL_ALIGN(2 * 8 * 1024, DDL_KILO_BYTE(2));
+			sz_context = DDL_FW_H264ENC_CONTEXT_SPACE_SIZE;
 			if (ddl) {
 				if (ddl->codec_data.encoder.
 					entropy_control.entropy_sel ==
@@ -792,7 +794,6 @@
 			sz_mb_info = DDL_ALIGN(mb_x * mb_y * 6 * 8,
 					DDL_KILO_BYTE(2));
 		}
-		sz_context = DDL_FW_OTHER_CONTEXT_SPACE_SIZE;
 		if (buf_size) {
 			buf_size->sz_cur_y      = sz_cur_y;
 			buf_size->sz_cur_c      = sz_cur_c;
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/irqdomain.h b/include/linux/irqdomain.h
index 99834e58..60ee260 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -89,8 +89,14 @@
 	     hw < d->hwirq_base + d->nr_irq; \
 	     hw++, irq = irq_domain_to_irq(d, hw))
 
-extern void irq_domain_add(struct irq_domain *domain);
+extern int irq_domain_add(struct irq_domain *domain);
 extern void irq_domain_del(struct irq_domain *domain);
+extern void irq_domain_register(struct irq_domain *domain);
+extern void irq_domain_register_irq(struct irq_domain *domain, int hwirq);
+extern void irq_domain_unregister(struct irq_domain *domain);
+extern void irq_domain_unregister_irq(struct irq_domain *domain, int hwirq);
+extern int irq_domain_find_free_range(unsigned int from, unsigned int cnt);
+
 #endif /* CONFIG_IRQ_DOMAIN */
 
 #if defined(CONFIG_IRQ_DOMAIN) && defined(CONFIG_OF_IRQ)
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/tzcom.h b/include/linux/tzcom.h
index a1b3dfc..448ab2a 100644
--- a/include/linux/tzcom.h
+++ b/include/linux/tzcom.h
@@ -6,6 +6,7 @@
 #include <linux/types.h>
 #include <linux/ioctl.h>
 
+#define MAX_ION_FD  4
 /**
  * struct tzcom_register_svc_op_req - for register service ioctl request
  * @svc_id - service id (shared between userspace and TZ)
@@ -49,6 +50,8 @@
 /**
  * struct tzcom_send_cmd_op_req - for send command ioctl request
  * @cmd_id - command to execute on TZBSP side
+ * @ifd_data_fd - ion handle to some memory allocated in user space
+ * @cmd_buf_offset - command buffer offset
  * @cmd_len - command buffer length
  * @cmd_buf - command buffer
  * @resp_len - response buffer length
@@ -63,6 +66,34 @@
 };
 
 /**
+ * struct tzcom_ion_fd_info - ion fd handle data information
+ * @fd - ion handle to some memory allocated in user space
+ * @cmd_buf_offset - command buffer offset
+ */
+struct tzcom_ion_fd_info {
+	int32_t fd;
+	uint32_t cmd_buf_offset;
+};
+
+/**
+ * struct tzcom_send_cmd_op_req - for send command ioctl request
+ * @cmd_id - command to execute on TZBSP side
+ * @ifd_data_fd - ion handle to some memory allocated in user space
+ * @cmd_buf_offset - command buffer offset
+ * @cmd_len - command buffer length
+ * @cmd_buf - command buffer
+ * @resp_len - response buffer length
+ * @resp_buf - response buffer
+ */
+struct tzcom_send_cmd_fd_op_req {
+	uint32_t cmd_id; /* in */
+	struct tzcom_ion_fd_info ifd_data[MAX_ION_FD];
+	unsigned int cmd_len; /* in */
+	void *cmd_buf; /* in */
+	unsigned int resp_len; /* in/out */
+	void *resp_buf; /* in/out */
+};
+/**
  * struct tzcom_cont_cmd_op_req - for continue command ioctl request. used
  * as a trigger from HLOS service to notify TZCOM that it's done with its
  * operation and provide the response for TZCOM can continue the incomplete
@@ -99,5 +130,7 @@
 	_IOWR(TZCOM_IOC_MAGIC, 5, struct tzcom_cont_cmd_op_req)
 
 #define TZCOM_IOCTL_ABORT_REQ _IO(TZCOM_IOC_MAGIC, 6)
-
+/* For TZ service */
+#define TZCOM_IOCTL_SEND_CMD_FD_REQ \
+	_IOWR(TZCOM_IOC_MAGIC, 7, struct tzcom_send_cmd_fd_op_req)
 #endif /* __TZCOM_H_ */
diff --git a/include/media/radio-iris.h b/include/media/radio-iris.h
index 536679f..8b753bd 100644
--- a/include/media/radio-iris.h
+++ b/include/media/radio-iris.h
@@ -690,7 +690,7 @@
 #define MAX_PS_LENGTH	(96)
 #define MAX_RT_LENGTH	(64)
 #define RDS_GRP_CNTR_LEN (36)
-
+#define RX_RT_DATA_LENGTH (63)
 /* Search direction */
 #define SRCH_DIR_UP		(0)
 #define SRCH_DIR_DOWN		(1)
diff --git a/include/media/videobuf2-msm-mem.h b/include/media/videobuf2-msm-mem.h
index 916c458..0c7cf8c 100644
--- a/include/media/videobuf2-msm-mem.h
+++ b/include/media/videobuf2-msm-mem.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -60,6 +60,7 @@
 	int subsys_id;
 	unsigned long mapped_phyaddr;
 	struct ion_handle *ion_handle;
+	struct ion_client *client;
 };
 void videobuf2_queue_pmem_contig_init(struct vb2_queue *q,
 					enum v4l2_buf_type type,
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 200ce83..3b5340b 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -13,20 +13,51 @@
  * irq_domain_add() - Register an irq_domain
  * @domain: ptr to initialized irq_domain structure
  *
- * Registers an irq_domain structure.  The irq_domain must at a minimum be
+ * Adds a irq_domain structure.  The irq_domain must at a minimum be
+ * initialized with an ops structure pointer, and either a ->to_irq hook or
+ * a valid irq_base value.  The irq range must be mutually exclusive with
+ * domains already registered. Everything else is optional.
+ */
+int irq_domain_add(struct irq_domain *domain)
+{
+	struct irq_domain *curr;
+	uint32_t d_highirq = domain->irq_base + domain->nr_irq - 1;
+
+	if (!domain->nr_irq)
+		return -EINVAL;
+
+	mutex_lock(&irq_domain_mutex);
+	/* insert in ascending order of domain->irq_base */
+	list_for_each_entry(curr, &irq_domain_list, list) {
+		uint32_t c_highirq = curr->irq_base + curr->nr_irq - 1;
+		if (domain->irq_base < curr->irq_base &&
+		    d_highirq < curr->irq_base) {
+			break;
+		}
+		if (d_highirq <= c_highirq) {
+			mutex_unlock(&irq_domain_mutex);
+			return -EINVAL;
+		}
+	}
+	list_add_tail(&domain->list, &curr->list);
+	mutex_unlock(&irq_domain_mutex);
+
+	return 0;
+}
+
+/**
+ * irq_domain_register() - Register an entire irq_domain
+ * @domain: ptr to initialized irq_domain structure
+ *
+ * Registers the entire irq_domain.  The irq_domain must at a minimum be
  * initialized with an ops structure pointer, and either a ->to_irq hook or
  * a valid irq_base value.  Everything else is optional.
  */
-void irq_domain_add(struct irq_domain *domain)
+void irq_domain_register(struct irq_domain *domain)
 {
 	struct irq_data *d;
 	int hwirq, irq;
 
-	/*
-	 * This assumes that the irq_domain owner has already allocated
-	 * the irq_descs.  This block will be removed when support for dynamic
-	 * allocation of irq_descs is added to irq_domain.
-	 */
 	irq_domain_for_each_irq(domain, hwirq, irq) {
 		d = irq_get_irq_data(irq);
 		if (!d) {
@@ -41,24 +72,55 @@
 		d->domain = domain;
 		d->hwirq = hwirq;
 	}
-
-	mutex_lock(&irq_domain_mutex);
-	list_add(&domain->list, &irq_domain_list);
-	mutex_unlock(&irq_domain_mutex);
 }
 
 /**
- * irq_domain_del() - Unregister an irq_domain
+ * irq_domain_register_irq() - Register an irq_domain
+ * @domain: ptr to initialized irq_domain structure
+ * @hwirq: irq_domain hwirq to register
+ *
+ * Registers a specific hwirq within the irq_domain.  The irq_domain
+ * must at a minimum be initialized with an ops structure pointer, and
+ * either a ->to_irq hook or a valid irq_base value.  Everything else is
+ * optional.
+ */
+void irq_domain_register_irq(struct irq_domain *domain, int hwirq)
+{
+	struct irq_data *d;
+
+	d = irq_get_irq_data(irq_domain_to_irq(domain, hwirq));
+	if (!d) {
+		WARN(1, "error: assigning domain to non existant irq_desc");
+		return;
+	}
+	if (d->domain) {
+		/* things are broken; just report, don't clean up */
+		WARN(1, "error: irq_desc already assigned to a domain");
+		return;
+	}
+	d->domain = domain;
+	d->hwirq = hwirq;
+}
+
+/**
+ * irq_domain_del() - Removes a irq_domain from the system
  * @domain: ptr to registered irq_domain.
  */
 void irq_domain_del(struct irq_domain *domain)
 {
-	struct irq_data *d;
-	int hwirq, irq;
-
 	mutex_lock(&irq_domain_mutex);
 	list_del(&domain->list);
 	mutex_unlock(&irq_domain_mutex);
+}
+
+/**
+ * irq_domain_unregister() - Unregister an irq_domain
+ * @domain: ptr to registered irq_domain.
+ */
+void irq_domain_unregister(struct irq_domain *domain)
+{
+	struct irq_data *d;
+	int hwirq, irq;
 
 	/* Clear the irq_domain assignments */
 	irq_domain_for_each_irq(domain, hwirq, irq) {
@@ -67,6 +129,60 @@
 	}
 }
 
+/**
+ * irq_domain_unregister_irq() - Unregister a hwirq within a irq_domain
+ * @domain: ptr to registered irq_domain.
+ * @hwirq: irq_domain hwirq to unregister.
+ */
+void irq_domain_unregister_irq(struct irq_domain *domain, int hwirq)
+{
+	struct irq_data *d;
+
+	/* Clear the irq_domain assignment */
+	d = irq_get_irq_data(irq_domain_to_irq(domain, hwirq));
+	d->domain = NULL;
+}
+
+/**
+ * irq_domain_find_free_range() - Find an available irq range
+ * @from: lowest logical irq number to request from
+ * @cnt: number of interrupts to search for
+ *
+ * Finds an available logical irq range from the domains specified
+ * on the system. The from parameter can be used to allocate a range
+ * at least as great as the specified irq number.
+ */
+int irq_domain_find_free_range(unsigned int from, unsigned int cnt)
+{
+	struct irq_domain *curr, *prev = NULL;
+
+	if (list_empty(&irq_domain_list))
+		return from;
+
+	list_for_each_entry(curr, &irq_domain_list, list) {
+		if (prev == NULL) {
+			if ((from + cnt - 1) < curr->irq_base)
+				return from;
+		} else {
+			uint32_t p_next_irq = prev->irq_base + prev->nr_irq;
+			uint32_t start_irq;
+			if (from >= curr->irq_base)
+				continue;
+			if (from < p_next_irq)
+				start_irq = p_next_irq;
+			else
+				start_irq = from;
+			if ((curr->irq_base - start_irq) >= cnt)
+				return p_next_irq;
+		}
+		prev = curr;
+	}
+	curr = list_entry(curr->list.prev, struct irq_domain, list);
+
+	return from > curr->irq_base + curr->nr_irq ?
+	       from : curr->irq_base + curr->nr_irq;
+}
+
 #if defined(CONFIG_OF_IRQ)
 /**
  * irq_create_of_mapping() - Map a linux irq number from a DT interrupt spec
@@ -91,6 +207,7 @@
 	list_for_each_entry(domain, &irq_domain_list, list) {
 		if (!domain->ops->dt_translate)
 			continue;
+
 		rc = domain->ops->dt_translate(domain, controller,
 					intspec, intsize, &hwirq, &type);
 		if (rc == 0)
@@ -154,6 +271,7 @@
 void irq_domain_add_simple(struct device_node *controller, int irq_base)
 {
 	struct irq_domain *domain;
+	int rc;
 
 	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
 	if (!domain) {
@@ -164,7 +282,12 @@
 	domain->irq_base = irq_base;
 	domain->of_node = of_node_get(controller);
 	domain->ops = &irq_domain_simple_ops;
-	irq_domain_add(domain);
+	rc = irq_domain_add(domain);
+	if (rc) {
+		WARN(1, "Unable to create irq domain\n");
+		return;
+	}
+	irq_domain_register(domain);
 }
 EXPORT_SYMBOL_GPL(irq_domain_add_simple);
 
diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c
index 1f06468..6fd4ffd 100644
--- a/kernel/trace/trace_printk.c
+++ b/kernel/trace/trace_printk.c
@@ -59,18 +59,19 @@
 			continue;
 		}
 
+		fmt = NULL;
 		tb_fmt = kmalloc(sizeof(*tb_fmt), GFP_KERNEL);
-		if (tb_fmt)
+		if (tb_fmt) {
 			fmt = kmalloc(strlen(*iter) + 1, GFP_KERNEL);
-		if (tb_fmt && fmt) {
-			list_add_tail(&tb_fmt->list, &trace_bprintk_fmt_list);
-			strcpy(fmt, *iter);
-			tb_fmt->fmt = fmt;
-			*iter = tb_fmt->fmt;
-		} else {
-			kfree(tb_fmt);
-			*iter = NULL;
+			if (fmt) {
+				list_add_tail(&tb_fmt->list, &trace_bprintk_fmt_list);
+				strcpy(fmt, *iter);
+				tb_fmt->fmt = fmt;
+			} else
+				kfree(tb_fmt);
 		}
+		*iter = fmt;
+
 	}
 	mutex_unlock(&btrace_mutex);
 }
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