Merge "msm: smd_pkt: Register platform driver with the SMD channel name" into msm-3.4
diff --git a/arch/arm/boot/dts/msmcopper.dtsi b/arch/arm/boot/dts/msmcopper.dtsi
index 5fe99df..bc7c5f0 100644
--- a/arch/arm/boot/dts/msmcopper.dtsi
+++ b/arch/arm/boot/dts/msmcopper.dtsi
@@ -402,6 +402,7 @@
 		compatible = "qcom,mdss_mdp";
 		reg = <0xfd900000 0x22100>;
 		interrupts = <0 72 0>;
+		vdd-supply = <&gdsc_mdss>;
 	};
 
 	qcom,mdss_wb_panel {
diff --git a/arch/arm/configs/msm-copper_defconfig b/arch/arm/configs/msm-copper_defconfig
index 8b9fa0fe..57cd263 100644
--- a/arch/arm/configs/msm-copper_defconfig
+++ b/arch/arm/configs/msm-copper_defconfig
@@ -173,6 +173,7 @@
 CONFIG_MMC=y
 CONFIG_MMC_PERF_PROFILING=y
 CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_CLKGATE=y
 CONFIG_MMC_PARANOID_SD_INIT=y
 CONFIG_MMC_BLOCK_MINORS=32
 # CONFIG_MMC_BLOCK_BOUNCE is not set
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index e37b28b..778128b 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -616,16 +616,14 @@
 	atomic_set(&armpmu->active_events, 0);
 	mutex_init(&armpmu->reserve_mutex);
 
-	armpmu->pmu = (struct pmu) {
-		.pmu_enable	= armpmu_enable,
-		.pmu_disable	= armpmu_disable,
-		.event_init	= armpmu_event_init,
-		.add		= armpmu_add,
-		.del		= armpmu_del,
-		.start		= armpmu_start,
-		.stop		= armpmu_stop,
-		.read		= armpmu_read,
-	};
+	armpmu->pmu.pmu_enable = armpmu_enable;
+	armpmu->pmu.pmu_disable = armpmu_disable;
+	armpmu->pmu.event_init = armpmu_event_init;
+	armpmu->pmu.add = armpmu_add;
+	armpmu->pmu.del = armpmu_del;
+	armpmu->pmu.start = armpmu_start;
+	armpmu->pmu.stop = armpmu_stop;
+	armpmu->pmu.read = armpmu_read;
 }
 
 int armpmu_register(struct arm_pmu *armpmu, char *name, int type)
@@ -857,14 +855,12 @@
 		case 0x02D0:    /* 8x60 */
 //			fabricmon_pmu_init();
 			cpu_pmu = armv7_scorpionmp_pmu_init();
-//			scorpionmp_l2_pmu_init();
 			break;
 		case 0x0490:    /* 8960 sim */
 		case 0x04D0:    /* 8960 */
 		case 0x06F0:    /* 8064 */
 //			fabricmon_pmu_init();
 			cpu_pmu = armv7_krait_pmu_init();
-//			krait_l2_pmu_init();
 			break;
 		}
 	}
diff --git a/arch/arm/kernel/perf_event_msm.c b/arch/arm/kernel/perf_event_msm.c
index 46fa8fe..90c9c9e 100644
--- a/arch/arm/kernel/perf_event_msm.c
+++ b/arch/arm/kernel/perf_event_msm.c
@@ -720,6 +720,8 @@
 	.start			= armv7pmu_start,
 	.stop			= armv7pmu_stop,
 	.reset			= scorpion_pmu_reset,
+	.test_set_event_constraints	= msm_test_set_ev_constraint,
+	.clear_event_constraints	= msm_clear_ev_constraint,
 	.max_period		= (1LLU << 32) - 1,
 };
 
@@ -728,6 +730,7 @@
 	scorpion_pmu.id		= ARM_PERF_PMU_ID_SCORPION;
 	scorpion_pmu.name	= "ARMv7 Scorpion";
 	scorpion_pmu.num_events	= armv7_read_num_pmnc_events();
+	scorpion_pmu.pmu.attr_groups	= msm_l1_pmu_attr_grps;
 	scorpion_clear_pmuregs();
 	return &scorpion_pmu;
 }
@@ -737,6 +740,7 @@
 	scorpion_pmu.id		= ARM_PERF_PMU_ID_SCORPIONMP;
 	scorpion_pmu.name	= "ARMv7 Scorpion-MP";
 	scorpion_pmu.num_events	= armv7_read_num_pmnc_events();
+	scorpion_pmu.pmu.attr_groups	= msm_l1_pmu_attr_grps;
 	scorpion_clear_pmuregs();
 	return &scorpion_pmu;
 }
diff --git a/arch/arm/kernel/perf_event_msm_krait.c b/arch/arm/kernel/perf_event_msm_krait.c
index 1b115b4..8d8f47a 100644
--- a/arch/arm/kernel/perf_event_msm_krait.c
+++ b/arch/arm/kernel/perf_event_msm_krait.c
@@ -573,10 +573,10 @@
  */
 static int msm_test_set_ev_constraint(struct perf_event *event)
 {
-	u32 krait_evt_type = event->attr.config & KRAIT_EVENT_MASK;
-	u8 prefix = (krait_evt_type & 0xF0000) >> 16;
-	u8 reg = (krait_evt_type & 0x0F000) >> 12;
-	u8 group = krait_evt_type & 0x0000F;
+	u32 evt_type = event->attr.config & KRAIT_EVENT_MASK;
+	u8 prefix = (evt_type & 0xF0000) >> 16;
+	u8 reg = (evt_type & 0x0F000) >> 12;
+	u8 group = evt_type & 0x0000F;
 	u64 cpu_pmu_bitmap = __get_cpu_var(pmu_bitmap);
 	u64 bitmap_t;
 
@@ -598,10 +598,10 @@
 
 static int msm_clear_ev_constraint(struct perf_event *event)
 {
-	u32 krait_evt_type = event->attr.config & KRAIT_EVENT_MASK;
-	u8 prefix = (krait_evt_type & 0xF0000) >> 16;
-	u8 reg = (krait_evt_type & 0x0F000) >> 12;
-	u8 group = krait_evt_type & 0x0000F;
+	u32 evt_type = event->attr.config & KRAIT_EVENT_MASK;
+	u8 prefix = (evt_type & 0xF0000) >> 16;
+	u8 reg = (evt_type & 0x0F000) >> 12;
+	u8 group = evt_type & 0x0000F;
 	u64 cpu_pmu_bitmap = __get_cpu_var(pmu_bitmap);
 	u64 bitmap_t;
 
@@ -636,6 +636,34 @@
 	.max_period		= (1LLU << 32) - 1,
 };
 
+/* NRCCG format for perf RAW codes. */
+PMU_FORMAT_ATTR(prefix,	"config:16-19");
+PMU_FORMAT_ATTR(reg,	"config:12-15");
+PMU_FORMAT_ATTR(code,	"config:4-11");
+PMU_FORMAT_ATTR(grp,	"config:0-3");
+
+static struct attribute *msm_l1_ev_formats[] = {
+	&format_attr_prefix.attr,
+	&format_attr_reg.attr,
+	&format_attr_code.attr,
+	&format_attr_grp.attr,
+	NULL,
+};
+
+/*
+ * Format group is essential to access PMU's from userspace
+ * via their .name field.
+ */
+static struct attribute_group msm_pmu_format_group = {
+	.name = "format",
+	.attrs = msm_l1_ev_formats,
+};
+
+static const struct attribute_group *msm_l1_pmu_attr_grps[] = {
+	&msm_pmu_format_group,
+	NULL,
+};
+
 int get_krait_ver(void)
 {
 	int ver = 0;
@@ -655,6 +683,7 @@
 	krait_pmu.name	        = "ARMv7 Krait";
 	krait_pmu.map_event	= krait_8960_map_event;
 	krait_pmu.num_events	= armv7_read_num_pmnc_events();
+	krait_pmu.pmu.attr_groups	= msm_l1_pmu_attr_grps;
 	krait_clear_pmuregs();
 
 	krait_ver = get_krait_ver();
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index d1ab4dd..776bf40 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -347,12 +347,14 @@
 	select ARCH_MSM_SCORPION
 	select MSM_SMP
 	select HAVE_ARCH_HAS_CURRENT_TIMER
+	select MSM_JTAG if MSM_QDSS
 	bool
 
 config  ARCH_MSM_KRAITMP
 	select ARCH_MSM_KRAIT
 	select MSM_SMP
 	select HAVE_ARCH_HAS_CURRENT_TIMER
+	select MSM_JTAG if MSM_QDSS
 	bool
 	select HAVE_HW_BRKPT_RESERVED_RW_ACCESS
 
@@ -2074,9 +2076,15 @@
 		enabled via another mechanism.
 
 config MSM_JTAG
-        bool "JTAG debug and trace support"
+	bool "JTAG and kernel debug and trace support across power collapse"
 	help
-          Add additional support for JTAG kernel debugging and tracing.
+	  Enables support for kernel debugging (specifically breakpoints) and
+	  processor tracing across power collapse both for JTag and OS hosted
+	  software running on the target. Enabling this will ensure debug
+	  and ETM registers are saved and restored across power collapse.
+
+	  For production builds, you should probably say 'N' here to avoid
+	  potential power, performance and memory penalty.
 
 config MSM_ETM
 	tristate "Enable MSM ETM and ETB"
@@ -2085,30 +2093,6 @@
 	help
 	  Enables embedded trace collection on MSM8660
 
-config MSM_QDSS
-	bool "Qualcomm Debug Subsystem"
-	select MSM_JTAG
-	help
-	  Enables support for Qualcomm Debug Subsystem.
-
-config MSM_QDSS_STM_DEFAULT_ENABLE
-	bool "Turn on QDSS STM Tracing by Default"
-	depends on MSM_QDSS
-	help
-	  Turns on QDSS STM tracing (hardware assisted software
-	  instrumentation based tracing) by default. Otherwise, tracing is
-	  disabled by default but can be enabled via sysfs.
-
-	  For production builds, you should probably say 'N' here to avoid
-	  potential power, performance and memory penalty.
-
-config MSM_QDSS_ETM_DEFAULT_ENABLE
-	bool "Turn on QDSS ETM Tracing by Default"
-	depends on MSM_QDSS
-	help
-	  Turns on QDSS ETM tracing by default. Otherwise, tracing is
-	  disabled by default but can be enabled by other means.
-
 config MSM_SLEEP_STATS
 	bool "Enable exporting of MSM sleep stats to userspace"
 	depends on CPU_IDLE
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 8315d70..ec8de9f 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -55,7 +55,6 @@
 
 msm-etm-objs := etm.o
 obj-$(CONFIG_MSM_ETM) += msm-etm.o
-obj-$(CONFIG_MSM_QDSS) += qdss.o qdss-etb.o qdss-tpiu.o qdss-funnel.o qdss-stm.o qdss-etm.o
 
 quiet_cmd_mkrpcsym = MKCAP   $@
       cmd_mkrpcsym = $(PERL) $(srctree)/$(src)/mkrpcsym.pl $< $@
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index d29fee6..6c14efa 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -735,10 +735,6 @@
 	{ 1, {  1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1175000 },
 	{ 1, {  1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1175000 },
 	{ 1, {  1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1200000 },
-	{ 1, {  1242000, HFPLL, 1, 0, 0x2E }, L2(16), 1200000 },
-	{ 1, {  1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1225000 },
-	{ 1, {  1350000, HFPLL, 1, 0, 0x32 }, L2(16), 1225000 },
-	{ 1, {  1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1237500 },
 	{ 0, { 0 } }
 };
 
@@ -760,10 +756,6 @@
 	{ 1, {  1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1150000 },
 	{ 1, {  1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1150000 },
 	{ 1, {  1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1175000 },
-	{ 1, {  1242000, HFPLL, 1, 0, 0x2E }, L2(16), 1175000 },
-	{ 1, {  1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1200000 },
-	{ 1, {  1350000, HFPLL, 1, 0, 0x32 }, L2(16), 1200000 },
-	{ 1, {  1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1212500 },
 	{ 0, { 0 } }
 };
 
@@ -785,10 +777,6 @@
 	{ 1, {  1080000, HFPLL, 1, 0, 0x28 }, L2(16), 1100000 },
 	{ 1, {  1134000, HFPLL, 1, 0, 0x2A }, L2(16), 1100000 },
 	{ 1, {  1188000, HFPLL, 1, 0, 0x2C }, L2(16), 1125000 },
-	{ 1, {  1242000, HFPLL, 1, 0, 0x2E }, L2(16), 1125000 },
-	{ 1, {  1296000, HFPLL, 1, 0, 0x30 }, L2(16), 1150000 },
-	{ 1, {  1350000, HFPLL, 1, 0, 0x32 }, L2(16), 1150000 },
-	{ 1, {  1404000, HFPLL, 1, 0, 0x34 }, L2(16), 1162500 },
 	{ 0, { 0 } }
 };
 /* TODO: Update vdd_dig, vdd_mem and bw when data is available. */
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index d53e471..3df566c 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -238,11 +238,12 @@
 static DEFINE_SPINLOCK(wakelock_reference_lock);
 static int wakelock_reference_count;
 static int a2_pc_disabled_wakelock_skipped;
-static int disconnect_ack;
+static int disconnect_ack = 1;
 static LIST_HEAD(bam_other_notify_funcs);
 static DEFINE_MUTEX(smsm_cb_lock);
 static DEFINE_MUTEX(delayed_ul_vote_lock);
 static int need_delayed_ul_vote;
+static int power_management_only_mode;
 
 struct outside_notify_func {
 	void (*notify)(void *, int, unsigned long);
@@ -561,9 +562,9 @@
 		bam_dmux_log("%s: opening cid %d PC enabled\n", __func__,
 				rx_hdr->ch_id);
 		handle_bam_mux_cmd_open(rx_hdr);
-		if (rx_hdr->reserved & ENABLE_DISCONNECT_ACK) {
-			bam_dmux_log("%s: activating disconnect ack\n");
-			disconnect_ack = 1;
+		if (!(rx_hdr->reserved & ENABLE_DISCONNECT_ACK)) {
+			bam_dmux_log("%s: deactivating disconnect ack\n");
+			disconnect_ack = 0;
 		}
 		dev_kfree_skb_any(rx_skb);
 		break;
@@ -1688,21 +1689,28 @@
 
 	in_global_reset = 0;
 	vote_dfab();
-	i = sps_device_reset(a2_device_handle);
-	if (i)
-		pr_err("%s: device reset failed rc = %d\n", __func__, i);
-	i = sps_connect(bam_tx_pipe, &tx_connection);
-	if (i)
-		pr_err("%s: tx connection failed rc = %d\n", __func__, i);
-	i = sps_connect(bam_rx_pipe, &rx_connection);
-	if (i)
-		pr_err("%s: rx connection failed rc = %d\n", __func__, i);
-	i = sps_register_event(bam_tx_pipe, &tx_register_event);
-	if (i)
-		pr_err("%s: tx event reg failed rc = %d\n", __func__, i);
-	i = sps_register_event(bam_rx_pipe, &rx_register_event);
-	if (i)
-		pr_err("%s: rx event reg failed rc = %d\n", __func__, i);
+	if (!power_management_only_mode) {
+		i = sps_device_reset(a2_device_handle);
+		if (i)
+			pr_err("%s: device reset failed rc = %d\n", __func__,
+									i);
+		i = sps_connect(bam_tx_pipe, &tx_connection);
+		if (i)
+			pr_err("%s: tx connection failed rc = %d\n", __func__,
+									i);
+		i = sps_connect(bam_rx_pipe, &rx_connection);
+		if (i)
+			pr_err("%s: rx connection failed rc = %d\n", __func__,
+									i);
+		i = sps_register_event(bam_tx_pipe, &tx_register_event);
+		if (i)
+			pr_err("%s: tx event reg failed rc = %d\n", __func__,
+									i);
+		i = sps_register_event(bam_rx_pipe, &rx_register_event);
+		if (i)
+			pr_err("%s: rx event reg failed rc = %d\n", __func__,
+									i);
+	}
 
 	bam_connection_is_active = 1;
 
@@ -1711,7 +1719,8 @@
 
 	toggle_apps_ack();
 	complete_all(&bam_connection_completion);
-	queue_rx();
+	if (!power_management_only_mode)
+		queue_rx();
 }
 
 static void disconnect_to_bam(void)
@@ -1733,11 +1742,13 @@
 
 	/* tear down BAM connection */
 	INIT_COMPLETION(bam_connection_completion);
-	sps_disconnect(bam_tx_pipe);
-	sps_disconnect(bam_rx_pipe);
+	if (!power_management_only_mode) {
+		sps_disconnect(bam_tx_pipe);
+		sps_disconnect(bam_rx_pipe);
+		__memzero(rx_desc_mem_buf.base, rx_desc_mem_buf.size);
+		__memzero(tx_desc_mem_buf.base, tx_desc_mem_buf.size);
+	}
 	unvote_dfab();
-	__memzero(rx_desc_mem_buf.base, rx_desc_mem_buf.size);
-	__memzero(tx_desc_mem_buf.base, tx_desc_mem_buf.size);
 
 	mutex_lock(&bam_rx_pool_mutexlock);
 	while (!list_empty(&bam_rx_pool)) {
@@ -2081,7 +2092,6 @@
 	int ret;
 	void *a2_virt_addr;
 
-	unvote_dfab();
 	/* init BAM */
 	a2_virt_addr = ioremap_nocache(A2_PHYS_BASE, A2_PHYS_SIZE);
 	if (!a2_virt_addr) {
@@ -2114,6 +2124,10 @@
 	mutex_unlock(&delayed_ul_vote_lock);
 	toggle_apps_ack();
 
+	power_management_only_mode = 1;
+	bam_connection_is_active = 1;
+	complete_all(&bam_connection_completion);
+
 	return 0;
 
 register_bam_failed:
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index 622b213..7175123f 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -221,6 +221,7 @@
 	REGULATOR_SUPPLY("8921_lvs7",		NULL),
 	REGULATOR_SUPPLY("pll_vdd",		"pil_riva"),
 	REGULATOR_SUPPLY("lvds_vdda",		"lvds.0"),
+	REGULATOR_SUPPLY("hdmi_pll_fs",		"mdp.0"),
 	REGULATOR_SUPPLY("dsi1_vddio",		"mipi_dsi.1"),
 	REGULATOR_SUPPLY("hdmi_vdda",		"hdmi_msm.0"),
 };
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 1f5ea52..1a61dbb 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -78,6 +78,7 @@
 #include <mach/mdm2.h>
 #include <mach/msm_rtb.h>
 #include <linux/fmem.h>
+#include <mach/msm_cache_dump.h>
 
 #ifdef CONFIG_INPUT_MPU3050
 #include <linux/input/mpu3050.h>
@@ -629,6 +630,19 @@
 	msm8930_mdp_writeback(msm8930_reserve_table);
 }
 
+#ifdef CONFIG_MSM_CACHE_DUMP
+static void __init reserve_cache_dump_memory(void)
+{
+	unsigned int total;
+
+	total = msm8930_cache_dump_pdata.l1_size +
+		msm8930_cache_dump_pdata.l2_size;
+	msm8930_reserve_table[MEMTYPE_EBI1].size += total;
+}
+#else
+static void __init reserve_cache_dump_memory(void) { }
+#endif
+
 static void __init msm8930_calculate_reserve_sizes(void)
 {
 	size_pmem_devices();
@@ -636,6 +650,7 @@
 	reserve_ion_memory();
 	reserve_mdp_memory();
 	reserve_rtb_memory();
+	reserve_cache_dump_memory();
 }
 
 static struct reserve_info msm8930_reserve_info __initdata = {
@@ -2149,6 +2164,7 @@
 	&msm8960_device_cache_erp,
 	&msm8930_iommu_domain_device,
 	&msm_tsens_device,
+	&msm8930_cache_dump_device,
 };
 
 static struct platform_device *cdp_devices[] __initdata = {
diff --git a/arch/arm/mach-msm/board-8930.h b/arch/arm/mach-msm/board-8930.h
index 925de45..9f6276c 100644
--- a/arch/arm/mach-msm/board-8930.h
+++ b/arch/arm/mach-msm/board-8930.h
@@ -141,3 +141,4 @@
 #define MSM_8930_GSBI12_QUP_I2C_BUS_ID 12
 
 extern struct msm_rtb_platform_data msm8930_rtb_pdata;
+extern struct msm_cache_dump_platform_data msm8930_cache_dump_pdata;
diff --git a/arch/arm/mach-msm/board-8960-regulator.c b/arch/arm/mach-msm/board-8960-regulator.c
index bc5a892..6bd1b7d 100644
--- a/arch/arm/mach-msm/board-8960-regulator.c
+++ b/arch/arm/mach-msm/board-8960-regulator.c
@@ -116,6 +116,7 @@
 	REGULATOR_SUPPLY("8921_l23",		NULL),
 	REGULATOR_SUPPLY("dsi_vddio",		"mipi_dsi.1"),
 	REGULATOR_SUPPLY("hdmi_avdd",		"hdmi_msm.0"),
+	REGULATOR_SUPPLY("hdmi_pll_fs",		"mdp.0"),
 	REGULATOR_SUPPLY("pll_vdd",		"pil_riva"),
 	REGULATOR_SUPPLY("pll_vdd",		"pil_qdsp6v4.1"),
 	REGULATOR_SUPPLY("pll_vdd",		"pil_qdsp6v4.2"),
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 628a324..ec62388 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -1416,6 +1416,7 @@
 
 static struct msm_spi_platform_data msm8960_qup_spi_gsbi1_pdata = {
 	.max_clock_speed = 15060000,
+	.infinite_mode	 = 1
 };
 
 #ifdef CONFIG_USB_MSM_OTG_72K
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index 568de46..7181990 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -194,7 +194,8 @@
 
 /* Initial PM8018 GPIO configurations */
 static struct pm8xxx_gpio_init pm8018_gpios[] __initdata = {
-	PM8018_GPIO_OUTPUT(2,	0,	HIGH) /* EXT_LDO_EN_WLAN */
+	PM8018_GPIO_OUTPUT(2,	0,	HIGH), /* EXT_LDO_EN_WLAN */
+	PM8018_GPIO_OUTPUT(6,	0,	LOW), /* WLAN_CLK_PWR_REQ */
 };
 
 /* Initial PM8018 MPP configurations */
diff --git a/arch/arm/mach-msm/board-copper.c b/arch/arm/mach-msm/board-copper.c
index 85241a4..59cb797 100644
--- a/arch/arm/mach-msm/board-copper.c
+++ b/arch/arm/mach-msm/board-copper.c
@@ -268,7 +268,7 @@
 	},
 	{
 		.irq_config_id = SMD_Q6,
-		.subsys_name = "q6",
+		.subsys_name = "adsp",
 		.edge = SMD_APPS_QDSP,
 
 		.smd_int.irq_name = "adsp_smd_in",
diff --git a/arch/arm/mach-msm/board-fsm9xxx.c b/arch/arm/mach-msm/board-fsm9xxx.c
index b071353..0e2aa3b 100644
--- a/arch/arm/mach-msm/board-fsm9xxx.c
+++ b/arch/arm/mach-msm/board-fsm9xxx.c
@@ -89,6 +89,15 @@
 #define GPIO_USER_FIRST		58
 #define GPIO_USER_LAST		63
 
+#define GPIO_UIM_RESET		75
+#define GPIO_UIM_DATA_IO	76
+#define GPIO_UIM_CLOCK		77
+
+#define GPIO_PM_UIM_M_RST	26	/* UIM_RST input */
+#define GPIO_PM_UIM_RST		27	/* UIM_RST output */
+#define GPIO_PM_UIM_M_CLK	28	/* UIM_CLK input */
+#define GPIO_PM_UIM_CLK		29	/* UIM_CLK output */
+
 #define FPGA_SDCC_STATUS        0x8E0001A8
 
 /* Macros assume PMIC GPIOs start at 0 */
@@ -100,6 +109,8 @@
 
 #define PMIC_GPIO_5V_PA_PWR	21	/* PMIC GPIO Number 22 */
 #define PMIC_GPIO_4_2V_PA_PWR	22	/* PMIC GPIO Number 23 */
+#define PMIC_MPP_UIM_M_DATA	0	/* UIM_DATA input */
+#define PMIC_MPP_UIM_DATA	1	/* UIM_DATA output */
 #define PMIC_MPP_3		2	/* PMIC MPP Number 3 */
 #define PMIC_MPP_6		5	/* PMIC MPP Number 6 */
 #define PMIC_MPP_7		6	/* PMIC MPP Number 7 */
@@ -181,6 +192,10 @@
 			PM8XXX_MPP_AOUT_LVL_1V25_2, AOUT_CTRL_ENABLE),
 		PM8XXX_MPP_INIT(PMIC_MPP_6, A_OUTPUT,
 			PM8XXX_MPP_AOUT_LVL_1V25_2, AOUT_CTRL_ENABLE),
+		PM8XXX_MPP_INIT(PMIC_MPP_UIM_M_DATA, D_BI_DIR,
+			PM8058_MPP_DIG_LEVEL_L3, BI_PULLUP_30KOHM),
+		PM8XXX_MPP_INIT(PMIC_MPP_UIM_DATA, D_BI_DIR,
+			PM8058_MPP_DIG_LEVEL_L3, BI_PULLUP_30KOHM),
 	};
 
 	for (i = 0; i < ARRAY_SIZE(pm8058_mpps); i++) {
@@ -597,6 +612,52 @@
 }
 #endif
 
+static struct msm_gpio uart3_uim_config_data[] = {
+	{ GPIO_CFG(GPIO_UIM_RESET, 0, GPIO_CFG_OUTPUT,
+		GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), "UIM_Reset" },
+	{ GPIO_CFG(GPIO_UIM_DATA_IO, 2, GPIO_CFG_OUTPUT,
+		GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), "UIM_Data" },
+	{ GPIO_CFG(GPIO_UIM_CLOCK, 2, GPIO_CFG_OUTPUT,
+		GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), "UIM_Clock" },
+};
+
+static void fsm9xxx_init_uart3_uim(void)
+{
+	struct pm_gpio pmic_uim_gpio_in = {
+		.direction	= PM_GPIO_DIR_IN,
+		.pull		= PM_GPIO_PULL_NO,
+		.out_strength	= PM_GPIO_STRENGTH_HIGH,
+		.function	= PM_GPIO_FUNC_PAIRED,
+		.vin_sel	= PM8058_GPIO_VIN_L3,
+	};
+	struct pm_gpio pmic_uim_gpio_out = {
+		.direction	= PM_GPIO_DIR_OUT,
+		.pull		= PM_GPIO_PULL_NO,
+		.out_strength	= PM_GPIO_STRENGTH_HIGH,
+		.function	= PM_GPIO_FUNC_PAIRED,
+		.vin_sel	= PM8058_GPIO_VIN_L3,
+	};
+
+	/* TLMM */
+	msm_gpios_request_enable(uart3_uim_config_data,
+			ARRAY_SIZE(uart3_uim_config_data));
+
+	/* Put UIM to reset state */
+	gpio_direction_output(GPIO_UIM_RESET, 0);
+	gpio_set_value(GPIO_UIM_RESET, 0);
+	gpio_export(GPIO_UIM_RESET, false);
+
+	/* PMIC */
+	pm8xxx_gpio_config(PM8058_GPIO_PM_TO_SYS(GPIO_PM_UIM_M_RST),
+		&pmic_uim_gpio_in);
+	pm8xxx_gpio_config(PM8058_GPIO_PM_TO_SYS(GPIO_PM_UIM_RST),
+		&pmic_uim_gpio_out);
+	pm8xxx_gpio_config(PM8058_GPIO_PM_TO_SYS(GPIO_PM_UIM_M_CLK),
+		&pmic_uim_gpio_in);
+	pm8xxx_gpio_config(PM8058_GPIO_PM_TO_SYS(GPIO_PM_UIM_CLK),
+		&pmic_uim_gpio_out);
+}
+
 /*
  * SSBI
  */
@@ -833,6 +894,7 @@
 #if defined(CONFIG_SERIAL_MSM) || defined(CONFIG_MSM_SERIAL_DEBUGGER)
 	&msm_device_uart1,
 #endif
+	&msm_device_uart3,
 #if defined(CONFIG_QFP_FUSE)
 	&fsm_qfp_fuse_device,
 #endif
@@ -903,6 +965,7 @@
 #ifdef CONFIG_SERIAL_MSM_CONSOLE
 	fsm9xxx_init_uart1();
 #endif
+	fsm9xxx_init_uart3_uim();
 #ifdef CONFIG_I2C_SSBI
 	msm_device_ssbi2.dev.platform_data = &msm_i2c_ssbi2_pdata;
 	msm_device_ssbi3.dev.platform_data = &msm_i2c_ssbi3_pdata;
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index dc473e6..7db4bda 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -50,6 +50,7 @@
 #include <linux/atmel_maxtouch.h>
 #include <linux/fmem.h>
 #include <linux/msm_adc.h>
+#include <linux/ion.h>
 #include "devices.h"
 #include "timer.h"
 #include "board-msm7x27a-regulator.h"
@@ -167,6 +168,15 @@
 
 #endif
 
+#ifdef CONFIG_ION_MSM
+#define MSM_ION_HEAP_NUM        4
+static struct platform_device ion_dev;
+static int msm_ion_camera_size;
+static int msm_ion_audio_size;
+static int msm_ion_sf_size;
+#endif
+
+
 static struct android_usb_platform_data android_usb_pdata = {
 	.update_pid_and_serial_num = usb_diag_update_pid_and_serial_num,
 };
@@ -822,6 +832,9 @@
 	&asoc_msm_dai1,
 	&msm_batt_device,
 	&msm_adc_device,
+#ifdef CONFIG_ION_MSM
+	&ion_dev,
+#endif
 };
 
 static struct platform_device *msm8625_surf_devices[] __initdata = {
@@ -853,6 +866,81 @@
 }
 early_param("pmem_audio_size", pmem_audio_size_setup);
 
+static void fix_sizes(void)
+{
+	if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
+		pmem_mdp_size = MSM7x25A_MSM_PMEM_MDP_SIZE;
+		pmem_adsp_size = MSM7x25A_MSM_PMEM_ADSP_SIZE;
+	} else {
+		pmem_mdp_size = MSM_PMEM_MDP_SIZE;
+		pmem_adsp_size = MSM_PMEM_ADSP_SIZE;
+	}
+#ifdef CONFIG_ION_MSM
+	msm_ion_camera_size = pmem_adsp_size;
+	msm_ion_audio_size = (MSM_PMEM_AUDIO_SIZE + PMEM_KERNEL_EBI1_SIZE);
+	msm_ion_sf_size = pmem_mdp_size;
+#endif
+}
+
+#ifdef CONFIG_ION_MSM
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+static struct ion_co_heap_pdata co_ion_pdata = {
+	.adjacent_mem_id = INVALID_HEAP_ID,
+	.align = PAGE_SIZE,
+};
+#endif
+
+/**
+ * These heaps are listed in the order they will be allocated.
+ * Don't swap the order unless you know what you are doing!
+ */
+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
+		/* PMEM_ADSP = CAMERA */
+		{
+			.id	= ION_CAMERA_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_CAMERA_HEAP_NAME,
+			.memory_type = ION_EBI_TYPE,
+			.has_outer_cache = 1,
+			.extra_data = (void *)&co_ion_pdata,
+		},
+		/* PMEM_AUDIO */
+		{
+			.id	= ION_AUDIO_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_AUDIO_HEAP_NAME,
+			.memory_type = ION_EBI_TYPE,
+			.has_outer_cache = 1,
+			.extra_data = (void *)&co_ion_pdata,
+		},
+		/* PMEM_MDP = SF */
+		{
+			.id	= ION_SF_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_SF_HEAP_NAME,
+			.memory_type = ION_EBI_TYPE,
+			.has_outer_cache = 1,
+			.extra_data = (void *)&co_ion_pdata,
+		},
+#endif
+	}
+};
+
+static struct platform_device ion_dev = {
+	.name = "ion-msm",
+	.id = 1,
+	.dev = { .platform_data = &ion_pdata },
+};
+#endif
+
 static struct memtype_reserve msm7x27a_reserve_table[] __initdata = {
 	[MEMTYPE_SMI] = {
 	},
@@ -865,27 +953,22 @@
 };
 
 #ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 static struct android_pmem_platform_data *pmem_pdata_array[] __initdata = {
 		&android_pmem_adsp_pdata,
 		&android_pmem_audio_pdata,
 		&android_pmem_pdata,
 };
 #endif
+#endif
 
 static void __init size_pmem_devices(void)
 {
 #ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 	unsigned int i;
 	unsigned int reusable_count = 0;
 
-	if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
-		pmem_mdp_size = MSM7x25A_MSM_PMEM_MDP_SIZE;
-		pmem_adsp_size = MSM7x25A_MSM_PMEM_ADSP_SIZE;
-	} else {
-		pmem_mdp_size = MSM_PMEM_MDP_SIZE;
-		pmem_adsp_size = MSM_PMEM_ADSP_SIZE;
-	}
-
 	android_pmem_adsp_pdata.size = pmem_adsp_size;
 	android_pmem_pdata.size = pmem_mdp_size;
 	android_pmem_audio_pdata.size = pmem_audio_size;
@@ -910,29 +993,56 @@
 		}
 	}
 #endif
-
+#endif
 }
 
+#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 static void __init reserve_memory_for(struct android_pmem_platform_data *p)
 {
 	msm7x27a_reserve_table[p->memory_type].size += p->size;
 }
+#endif
+#endif
 
 static void __init reserve_pmem_memory(void)
 {
 #ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 	unsigned int i;
 	for (i = 0; i < ARRAY_SIZE(pmem_pdata_array); ++i)
 		reserve_memory_for(pmem_pdata_array[i]);
 
 	msm7x27a_reserve_table[MEMTYPE_EBI1].size += pmem_kernel_ebi1_size;
 #endif
+#endif
+}
+
+static void __init size_ion_devices(void)
+{
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	ion_pdata.heaps[1].size = msm_ion_camera_size;
+	ion_pdata.heaps[2].size = msm_ion_audio_size;
+	ion_pdata.heaps[3].size = msm_ion_sf_size;
+#endif
+}
+
+static void __init reserve_ion_memory(void)
+{
+#if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
+	msm7x27a_reserve_table[MEMTYPE_EBI1].size += msm_ion_camera_size;
+	msm7x27a_reserve_table[MEMTYPE_EBI1].size += msm_ion_audio_size;
+	msm7x27a_reserve_table[MEMTYPE_EBI1].size += msm_ion_sf_size;
+#endif
 }
 
 static void __init msm7x27a_calculate_reserve_sizes(void)
 {
+	fix_sizes();
 	size_pmem_devices();
 	reserve_pmem_memory();
+	size_ion_devices();
+	reserve_ion_memory();
 }
 
 static int msm7x27a_paddr_to_memtype(unsigned int paddr)
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
index 9c80c8b..8eb961c 100644
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -33,6 +33,7 @@
 #include <linux/msm_adc.h>
 #include <linux/fmem.h>
 #include <linux/regulator/msm-gpio-regulator.h>
+#include <linux/ion.h>
 #include <asm/mach/mmc.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -131,6 +132,14 @@
 #ifdef CONFIG_ARCH_MSM7X27A
 #define MSM_PMEM_MDP_SIZE       0x2300000
 #define MSM_PMEM_ADSP_SIZE      0x1200000
+
+#define MSM_ION_AUDIO_SIZE	(MSM_PMEM_AUDIO_SIZE + PMEM_KERNEL_EBI1_SIZE)
+#define MSM_ION_CAMERA_SIZE	MSM_PMEM_ADSP_SIZE
+#define MSM_ION_SF_SIZE		MSM_PMEM_MDP_SIZE
+#define MSM_ION_HEAP_NUM	4
+#ifdef CONFIG_ION_MSM
+static struct platform_device ion_dev;
+#endif
 #endif
 
 static struct android_usb_platform_data android_usb_pdata = {
@@ -708,6 +717,9 @@
 	&asoc_msm_dai1,
 	&msm_adc_device,
 	&fmem_device,
+#ifdef CONFIG_ION_MSM
+	&ion_dev,
+#endif
 };
 
 static struct platform_device *qrd7627a_devices[] __initdata = {
@@ -756,6 +768,68 @@
 }
 early_param("pmem_audio_size", pmem_audio_size_setup);
 
+#ifdef CONFIG_ION_MSM
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+static struct ion_co_heap_pdata co_ion_pdata = {
+	.adjacent_mem_id = INVALID_HEAP_ID,
+	.align = PAGE_SIZE,
+};
+#endif
+
+/**
+ * These heaps are listed in the order they will be allocated.
+ * Don't swap the order unless you know what you are doing!
+ */
+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
+		/* PMEM_ADSP = CAMERA */
+		{
+			.id	= ION_CAMERA_HEAP_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_CAMERA_HEAP_NAME,
+			.size	= MSM_ION_CAMERA_SIZE,
+			.memory_type = ION_EBI_TYPE,
+			.has_outer_cache = 1,
+			.extra_data = (void *)&co_ion_pdata,
+		},
+		/* PMEM_AUDIO */
+		{
+			.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,
+			.has_outer_cache = 1,
+			.extra_data = (void *)&co_ion_pdata,
+		},
+		/* PMEM_MDP = SF */
+		{
+			.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,
+			.has_outer_cache = 1,
+			.extra_data = (void *)&co_ion_pdata,
+		},
+#endif
+	}
+};
+
+static struct platform_device ion_dev = {
+	.name = "ion-msm",
+	.id = 1,
+	.dev = { .platform_data = &ion_pdata },
+};
+#endif
+
 static struct memtype_reserve msm7627a_reserve_table[] __initdata = {
 	[MEMTYPE_SMI] = {
 	},
@@ -768,16 +842,19 @@
 };
 
 #ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 static struct android_pmem_platform_data *pmem_pdata_array[] __initdata = {
 		&android_pmem_adsp_pdata,
 		&android_pmem_audio_pdata,
 		&android_pmem_pdata,
 };
 #endif
+#endif
 
 static void __init size_pmem_devices(void)
 {
 #ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 	unsigned int i;
 	unsigned int reusable_count = 0;
 
@@ -804,30 +881,46 @@
 			pdata->reusable = 0;
 		}
 	}
-
+#endif
 #endif
 }
 
+#ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 static void __init reserve_memory_for(struct android_pmem_platform_data *p)
 {
 	msm7627a_reserve_table[p->memory_type].size += p->size;
 }
+#endif
+#endif
 
 static void __init reserve_pmem_memory(void)
 {
 #ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 	unsigned int i;
 	for (i = 0; i < ARRAY_SIZE(pmem_pdata_array); ++i)
 		reserve_memory_for(pmem_pdata_array[i]);
 
 	msm7627a_reserve_table[MEMTYPE_EBI1].size += pmem_kernel_ebi1_size;
 #endif
+#endif
+}
+
+static void __init reserve_ion_memory(void)
+{
+#if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
+	msm7627a_reserve_table[MEMTYPE_EBI1].size += MSM_ION_CAMERA_SIZE;
+	msm7627a_reserve_table[MEMTYPE_EBI1].size += MSM_ION_AUDIO_SIZE;
+	msm7627a_reserve_table[MEMTYPE_EBI1].size += MSM_ION_SF_SIZE;
+#endif
 }
 
 static void __init msm7627a_calculate_reserve_sizes(void)
 {
 	size_pmem_devices();
 	reserve_pmem_memory();
+	reserve_ion_memory();
 }
 
 static int msm7627a_paddr_to_memtype(unsigned int paddr)
diff --git a/arch/arm/mach-msm/clock-7x30.c b/arch/arm/mach-msm/clock-7x30.c
index aa94be6..225ea2b 100644
--- a/arch/arm/mach-msm/clock-7x30.c
+++ b/arch/arm/mach-msm/clock-7x30.c
@@ -200,7 +200,7 @@
 #define PCOM_XO_TCXO	0
 #define PCOM_XO_LPXO	1
 
-static bool pcom_is_local(struct clk *clk)
+static bool pcom_is_local(struct clk *c)
 {
 	return false;
 }
@@ -2441,7 +2441,7 @@
 
 struct measure_sel {
 	u32 test_vector;
-	struct clk *clk;
+	struct clk *c;
 };
 
 static struct measure_sel measure_mux[] = {
@@ -2538,17 +2538,17 @@
 	{ CLK_TEST_LS(0x3F), &usb_hs_clk.c },
 };
 
-static struct measure_sel *find_measure_sel(struct clk *clk)
+static struct measure_sel *find_measure_sel(struct clk *c)
 {
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(measure_mux); i++)
-		if (measure_mux[i].clk == clk)
+		if (measure_mux[i].c == c)
 			return &measure_mux[i];
 	return NULL;
 }
 
-static int measure_clk_set_parent(struct clk *clk, struct clk *parent)
+static int measure_clk_set_parent(struct clk *c, struct clk *parent)
 {
 	struct measure_sel *p;
 	unsigned long flags;
@@ -2599,7 +2599,7 @@
 
 /* Perform a hardware rate measurement for a given clock.
    FOR DEBUG USE ONLY: Measurements take ~15 ms! */
-static unsigned long measure_clk_get_rate(struct clk *clk)
+static unsigned long measure_clk_get_rate(struct clk *c)
 {
 	unsigned long flags;
 	u32 regval, prph_web_reg_old;
@@ -2647,12 +2647,12 @@
 	return ret;
 }
 #else /* !CONFIG_DEBUG_FS */
-static int measure_clk_set_parent(struct clk *clk, struct clk *parent)
+static int measure_clk_set_parent(struct clk *c, struct clk *parent)
 {
 	return -EINVAL;
 }
 
-static unsigned long measure_clk_get_rate(struct clk *clk)
+static unsigned long measure_clk_get_rate(struct clk *c)
 {
 	return 0;
 }
@@ -2670,14 +2670,14 @@
 };
 
 /* Implementation for clk_set_flags(). */
-int soc_clk_set_flags(struct clk *clk, unsigned clk_flags)
+int soc_clk_set_flags(struct clk *c, unsigned clk_flags)
 {
 	uint32_t regval, ret = 0;
 	unsigned long flags;
 
 	spin_lock_irqsave(&local_clock_reg_lock, flags);
 
-	if (clk == &vfe_clk.c) {
+	if (c == &vfe_clk.c) {
 		regval = readl_relaxed(CAM_VFE_NS_REG);
 		/* Flag values chosen for backward compatibility
 		 * with proc_comm remote clock control. */
@@ -2701,17 +2701,15 @@
 	return ret;
 }
 
-static int msm7x30_clk_reset(struct clk *clk, enum clk_reset_action action)
+static int msm7x30_clk_reset(struct clk *c, enum clk_reset_action action)
 {
 	/* reset_mask is actually a proc_comm id */
-	unsigned id = to_rcg_clk(clk)->b.reset_mask;
-	return pc_clk_reset(id, action);
+	return pc_clk_reset(to_rcg_clk(c)->b.reset_mask, action);
 }
 
-static int soc_branch_clk_reset(struct clk *clk, enum clk_reset_action action)
+static int soc_branch_clk_reset(struct clk *c, enum clk_reset_action action)
 {
-	unsigned id = to_branch_clk(clk)->b.reset_mask;
-	return pc_clk_reset(id, action);
+	return pc_clk_reset(to_branch_clk(c)->b.reset_mask, action);
 }
 
 /*
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 7866fc7..fa91249 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -2858,9 +2858,9 @@
 	struct clk c;
 };
 
-static inline struct pix_rdi_clk *to_pix_rdi_clk(struct clk *clk)
+static inline struct pix_rdi_clk *to_pix_rdi_clk(struct clk *c)
 {
-	return container_of(clk, struct pix_rdi_clk, c);
+	return container_of(c, struct pix_rdi_clk, c);
 }
 
 static int pix_rdi_clk_set_rate(struct clk *c, unsigned long rate)
@@ -2868,7 +2868,7 @@
 	int ret, i;
 	u32 reg;
 	unsigned long flags;
-	struct pix_rdi_clk *clk = to_pix_rdi_clk(c);
+	struct pix_rdi_clk *rdi = to_pix_rdi_clk(c);
 	struct clk **mux_map = pix_rdi_mux_map;
 
 	/*
@@ -2889,32 +2889,32 @@
 		goto err;
 	}
 	/* Keep the new source on when switching inputs of an enabled clock */
-	if (clk->enabled) {
-		clk_disable(mux_map[clk->cur_rate]);
+	if (rdi->enabled) {
+		clk_disable(mux_map[rdi->cur_rate]);
 		clk_enable(mux_map[rate]);
 	}
 	spin_lock_irqsave(&local_clock_reg_lock, flags);
-	reg = readl_relaxed(clk->s2_reg);
-	reg &= ~clk->s2_mask;
-	reg |= rate == 2 ? clk->s2_mask : 0;
-	writel_relaxed(reg, clk->s2_reg);
+	reg = readl_relaxed(rdi->s2_reg);
+	reg &= ~rdi->s2_mask;
+	reg |= rate == 2 ? rdi->s2_mask : 0;
+	writel_relaxed(reg, rdi->s2_reg);
 	/*
 	 * Wait at least 6 cycles of slowest clock
 	 * for the glitch-free MUX to fully switch sources.
 	 */
 	mb();
 	udelay(1);
-	reg = readl_relaxed(clk->s_reg);
-	reg &= ~clk->s_mask;
-	reg |= rate == 1 ? clk->s_mask : 0;
-	writel_relaxed(reg, clk->s_reg);
+	reg = readl_relaxed(rdi->s_reg);
+	reg &= ~rdi->s_mask;
+	reg |= rate == 1 ? rdi->s_mask : 0;
+	writel_relaxed(reg, rdi->s_reg);
 	/*
 	 * Wait at least 6 cycles of slowest clock
 	 * for the glitch-free MUX to fully switch sources.
 	 */
 	mb();
 	udelay(1);
-	clk->cur_rate = rate;
+	rdi->cur_rate = rate;
 	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
 err:
 	for (i--; i >= 0; i--)
@@ -2931,12 +2931,12 @@
 static int pix_rdi_clk_enable(struct clk *c)
 {
 	unsigned long flags;
-	struct pix_rdi_clk *clk = to_pix_rdi_clk(c);
+	struct pix_rdi_clk *rdi = to_pix_rdi_clk(c);
 
 	spin_lock_irqsave(&local_clock_reg_lock, flags);
-	__branch_clk_enable_reg(&clk->b, clk->c.dbg_name);
+	__branch_enable_reg(&rdi->b, rdi->c.dbg_name);
 	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
-	clk->enabled = true;
+	rdi->enabled = true;
 
 	return 0;
 }
@@ -2944,24 +2944,22 @@
 static void pix_rdi_clk_disable(struct clk *c)
 {
 	unsigned long flags;
-	struct pix_rdi_clk *clk = to_pix_rdi_clk(c);
+	struct pix_rdi_clk *rdi = to_pix_rdi_clk(c);
 
 	spin_lock_irqsave(&local_clock_reg_lock, flags);
-	__branch_clk_disable_reg(&clk->b, clk->c.dbg_name);
+	__branch_disable_reg(&rdi->b, rdi->c.dbg_name);
 	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
-	clk->enabled = false;
+	rdi->enabled = false;
 }
 
-static int pix_rdi_clk_reset(struct clk *clk, enum clk_reset_action action)
+static int pix_rdi_clk_reset(struct clk *c, enum clk_reset_action action)
 {
-	return branch_reset(&to_pix_rdi_clk(clk)->b, action);
+	return branch_reset(&to_pix_rdi_clk(c)->b, action);
 }
 
 static struct clk *pix_rdi_clk_get_parent(struct clk *c)
 {
-	struct pix_rdi_clk *clk = to_pix_rdi_clk(c);
-
-	return pix_rdi_mux_map[clk->cur_rate];
+	return pix_rdi_mux_map[to_pix_rdi_clk(c)->cur_rate];
 }
 
 static int pix_rdi_clk_list_rate(struct clk *c, unsigned n)
@@ -2974,17 +2972,17 @@
 static enum handoff pix_rdi_clk_handoff(struct clk *c)
 {
 	u32 reg;
-	struct pix_rdi_clk *clk = to_pix_rdi_clk(c);
+	struct pix_rdi_clk *rdi = to_pix_rdi_clk(c);
 	enum handoff ret;
 
-	ret = branch_handoff(&clk->b, &clk->c);
+	ret = branch_handoff(&rdi->b, &rdi->c);
 	if (ret == HANDOFF_DISABLED_CLK)
 		return ret;
 
-	reg = readl_relaxed(clk->s_reg);
-	clk->cur_rate = reg & clk->s_mask ? 1 : 0;
-	reg = readl_relaxed(clk->s2_reg);
-	clk->cur_rate = reg & clk->s2_mask ? 2 : clk->cur_rate;
+	reg = readl_relaxed(rdi->s_reg);
+	rdi->cur_rate = reg & rdi->s_mask ? 1 : 0;
+	reg = readl_relaxed(rdi->s2_reg);
+	rdi->cur_rate = reg & rdi->s2_mask ? 2 : rdi->cur_rate;
 
 	return HANDOFF_ENABLED_CLK;
 }
@@ -3897,7 +3895,7 @@
 	},
 };
 
-static int hdmi_pll_clk_enable(struct clk *clk)
+static int hdmi_pll_clk_enable(struct clk *c)
 {
 	int ret;
 	unsigned long flags;
@@ -3907,7 +3905,7 @@
 	return ret;
 }
 
-static void hdmi_pll_clk_disable(struct clk *clk)
+static void hdmi_pll_clk_disable(struct clk *c)
 {
 	unsigned long flags;
 	spin_lock_irqsave(&local_clock_reg_lock, flags);
@@ -3915,12 +3913,12 @@
 	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
 }
 
-static unsigned long hdmi_pll_clk_get_rate(struct clk *clk)
+static unsigned long hdmi_pll_clk_get_rate(struct clk *c)
 {
 	return hdmi_pll_get_rate();
 }
 
-static struct clk *hdmi_pll_clk_get_parent(struct clk *clk)
+static struct clk *hdmi_pll_clk_get_parent(struct clk *c)
 {
 	return &pxo_clk.c;
 }
@@ -3975,12 +3973,12 @@
  * Unlike other clocks, the TV rate is adjusted through PLL
  * re-programming. It is also routed through an MND divider.
  */
-void set_rate_tv(struct rcg_clk *clk, struct clk_freq_tbl *nf)
+void set_rate_tv(struct rcg_clk *rcg, struct clk_freq_tbl *nf)
 {
 	unsigned long pll_rate = (unsigned long)nf->extra_freq_data;
 	if (pll_rate)
 		hdmi_pll_set_rate(pll_rate);
-	set_rate_mnd(clk, nf);
+	set_rate_mnd(rcg, nf);
 }
 
 static struct rcg_clk tv_src_clk = {
@@ -4585,6 +4583,7 @@
 DEFINE_CLK_RPM(mmfpb_clk, mmfpb_a_clk, MMFPB, NULL);
 DEFINE_CLK_RPM(sfab_clk, sfab_a_clk, SYSTEM_FABRIC, NULL);
 DEFINE_CLK_RPM(sfpb_clk, sfpb_a_clk, SFPB, NULL);
+DEFINE_CLK_RPM_QDSS(qdss_clk, qdss_a_clk);
 
 static DEFINE_CLK_VOTER(sfab_msmbus_a_clk, &sfab_a_clk.c, 0);
 static DEFINE_CLK_VOTER(sfab_tmr_a_clk, &sfab_a_clk.c, 0);
@@ -4616,7 +4615,7 @@
 #ifdef CONFIG_DEBUG_FS
 struct measure_sel {
 	u32 test_vector;
-	struct clk *clk;
+	struct clk *c;
 };
 
 static DEFINE_CLK_MEASURE(l2_m_clk);
@@ -4840,12 +4839,12 @@
 	{ TEST_CPUL2(0x5), &krait3_m_clk },
 };
 
-static struct measure_sel *find_measure_sel(struct clk *clk)
+static struct measure_sel *find_measure_sel(struct clk *c)
 {
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(measure_mux); i++)
-		if (measure_mux[i].clk == clk)
+		if (measure_mux[i].c == c)
 			return &measure_mux[i];
 	return NULL;
 }
@@ -4855,7 +4854,7 @@
 	int ret = 0;
 	u32 clk_sel;
 	struct measure_sel *p;
-	struct measure_clk *clk = to_measure_clk(c);
+	struct measure_clk *measure = to_measure_clk(c);
 	unsigned long flags;
 
 	if (!parent)
@@ -4871,9 +4870,9 @@
 	 * Program the test vector, measurement period (sample_ticks)
 	 * and scaling multiplier.
 	 */
-	clk->sample_ticks = 0x10000;
+	measure->sample_ticks = 0x10000;
 	clk_sel = p->test_vector & TEST_CLK_SEL_MASK;
-	clk->multiplier = 1;
+	measure->multiplier = 1;
 	switch (p->test_vector >> TEST_TYPE_SHIFT) {
 	case TEST_TYPE_PER_LS:
 		writel_relaxed(0x4030D00|BVAL(7, 0, clk_sel), CLK_TEST_REG);
@@ -4902,8 +4901,8 @@
 	case TEST_TYPE_CPUL2:
 		writel_relaxed(0x4030400, CLK_TEST_REG);
 		writel_relaxed(0x80|BVAL(5, 3, clk_sel), GCC_APCS_CLK_DIAG);
-		clk->sample_ticks = 0x4000;
-		clk->multiplier = 2;
+		measure->sample_ticks = 0x4000;
+		measure->multiplier = 2;
 		break;
 	default:
 		ret = -EPERM;
@@ -4946,7 +4945,7 @@
 	unsigned long flags;
 	u32 pdm_reg_backup, ringosc_reg_backup;
 	u64 raw_count_short, raw_count_full;
-	struct measure_clk *clk = to_measure_clk(c);
+	struct measure_clk *measure = to_measure_clk(c);
 	unsigned ret;
 
 	ret = clk_prepare_enable(&cxo_clk.c);
@@ -4973,7 +4972,7 @@
 	/* Run a short measurement. (~1 ms) */
 	raw_count_short = run_measurement(0x1000);
 	/* Run a full measurement. (~14 ms) */
-	raw_count_full = run_measurement(clk->sample_ticks);
+	raw_count_full = run_measurement(measure->sample_ticks);
 
 	writel_relaxed(ringosc_reg_backup, RINGOSC_NS_REG);
 	writel_relaxed(pdm_reg_backup, PDM_CLK_NS_REG);
@@ -4984,8 +4983,8 @@
 	else {
 		/* Compute rate in Hz. */
 		raw_count_full = ((raw_count_full * 10) + 15) * 4800000;
-		do_div(raw_count_full, ((clk->sample_ticks * 10) + 35));
-		ret = (raw_count_full * clk->multiplier);
+		do_div(raw_count_full, ((measure->sample_ticks * 10) + 35));
+		ret = (raw_count_full * measure->multiplier);
 	}
 
 	/* Route dbg_hs_clk to PLLTEST.  300mV single-ended amplitude. */
@@ -4997,12 +4996,12 @@
 	return ret;
 }
 #else /* !CONFIG_DEBUG_FS */
-static int measure_clk_set_parent(struct clk *clk, struct clk *parent)
+static int measure_clk_set_parent(struct clk *c, struct clk *parent)
 {
 	return -EINVAL;
 }
 
-static unsigned long measure_clk_get_rate(struct clk *clk)
+static unsigned long measure_clk_get_rate(struct clk *c)
 {
 	return 0;
 }
@@ -5070,6 +5069,12 @@
 	CLK_LOOKUP("mem_a_clk",		ebi1_msmbus_a_clk.c,	"msm_bus"),
 	CLK_LOOKUP("dfab_clk",		dfab_msmbus_clk.c,	"msm_bus"),
 	CLK_LOOKUP("dfab_a_clk",	dfab_msmbus_a_clk.c,	"msm_bus"),
+	CLK_LOOKUP("core_a_clk",	qdss_a_clk.c,		""),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,		"msm_etb.0"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,		"msm_tpiu.0"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,		"msm_funnel.0"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,		"msm_stm.0"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,		"msm_etm.0"),
 
 	CLK_LOOKUP("ebi1_clk",		ebi1_clk.c,		""),
 	CLK_LOOKUP("mmfpb_clk",		mmfpb_clk.c,		""),
@@ -5394,6 +5399,12 @@
 	CLK_LOOKUP("mem_a_clk",		ebi1_msmbus_a_clk.c,	"msm_bus"),
 	CLK_LOOKUP("dfab_clk",		dfab_msmbus_clk.c,	"msm_bus"),
 	CLK_LOOKUP("dfab_a_clk",	dfab_msmbus_a_clk.c,	"msm_bus"),
+	CLK_LOOKUP("core_a_clk",	qdss_a_clk.c,		""),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,		"msm_etb.0"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,		"msm_tpiu.0"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,		"msm_funnel.0"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,		"msm_stm.0"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,		"msm_etm.0"),
 
 	CLK_LOOKUP("ebi1_clk",		ebi1_clk.c,		NULL),
 	CLK_LOOKUP("mmfpb_clk",		mmfpb_clk.c,		NULL),
@@ -5710,6 +5721,12 @@
 	CLK_LOOKUP("mem_a_clk",		ebi1_msmbus_a_clk.c,	"msm_bus"),
 	CLK_LOOKUP("dfab_clk",		dfab_msmbus_clk.c,	"msm_bus"),
 	CLK_LOOKUP("dfab_a_clk",	dfab_msmbus_a_clk.c,	"msm_bus"),
+	CLK_LOOKUP("core_a_clk",	qdss_a_clk.c,		""),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,		"msm_etb.0"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,		"msm_tpiu.0"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,		"msm_funnel.0"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,		"msm_stm.0"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,		"msm_etm.0"),
 
 	CLK_LOOKUP("ebi1_clk",		ebi1_clk.c,		NULL),
 	CLK_LOOKUP("mmfpb_clk",		mmfpb_clk.c,		NULL),
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index 74d71a2..da7dca7 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -341,24 +341,24 @@
 	},
 };
 
-static int pll4_clk_enable(struct clk *clk)
+static int pll4_clk_enable(struct clk *c)
 {
 	struct msm_rpm_iv_pair iv = { MSM_RPM_ID_PLL_4, 1 };
 	return msm_rpm_set_noirq(MSM_RPM_CTX_SET_0, &iv, 1);
 }
 
-static void pll4_clk_disable(struct clk *clk)
+static void pll4_clk_disable(struct clk *c)
 {
 	struct msm_rpm_iv_pair iv = { MSM_RPM_ID_PLL_4, 0 };
 	msm_rpm_set_noirq(MSM_RPM_CTX_SET_0, &iv, 1);
 }
 
-static struct clk *pll4_clk_get_parent(struct clk *clk)
+static struct clk *pll4_clk_get_parent(struct clk *c)
 {
 	return &pxo_clk.c;
 }
 
-static bool pll4_clk_is_local(struct clk *clk)
+static bool pll4_clk_is_local(struct clk *c)
 {
 	return false;
 }
@@ -397,7 +397,7 @@
 
 /* Unlike other clocks, the TV rate is adjusted through PLL
  * re-programming. It is also routed through an MND divider. */
-static void set_rate_tv(struct rcg_clk *clk, struct clk_freq_tbl *nf)
+static void set_rate_tv(struct rcg_clk *rcg, struct clk_freq_tbl *nf)
 {
 	struct pll_rate *rate = nf->extra_freq_data;
 	uint32_t pll_mode, pll_config, misc_cc2;
@@ -426,7 +426,7 @@
 	writel_relaxed(pll_config, MM_PLL2_CONFIG_REG);
 
 	/* Configure MND. */
-	set_rate_mnd(clk, nf);
+	set_rate_mnd(rcg, nf);
 
 	/* Configure hdmi_ref_clk to be equal to the TV clock rate. */
 	misc_cc2 = readl_relaxed(MISC_CC2_REG);
@@ -3133,7 +3133,7 @@
 #ifdef CONFIG_DEBUG_FS
 struct measure_sel {
 	u32 test_vector;
-	struct clk *clk;
+	struct clk *c;
 };
 
 static struct measure_sel measure_mux[] = {
@@ -3308,12 +3308,12 @@
 	{ TEST_SC(0x42), &l2_m_clk },
 };
 
-static struct measure_sel *find_measure_sel(struct clk *clk)
+static struct measure_sel *find_measure_sel(struct clk *c)
 {
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(measure_mux); i++)
-		if (measure_mux[i].clk == clk)
+		if (measure_mux[i].c == c)
 			return &measure_mux[i];
 	return NULL;
 }
@@ -3323,7 +3323,7 @@
 	int ret = 0;
 	u32 clk_sel;
 	struct measure_sel *p;
-	struct measure_clk *clk = to_measure_clk(c);
+	struct measure_clk *measure = to_measure_clk(c);
 	unsigned long flags;
 
 	if (!parent)
@@ -3340,9 +3340,9 @@
 	 * and scaling factors (multiplier, divider).
 	 */
 	clk_sel = p->test_vector & TEST_CLK_SEL_MASK;
-	clk->sample_ticks = 0x10000;
-	clk->multiplier = 1;
-	clk->divider = 1;
+	measure->sample_ticks = 0x10000;
+	measure->multiplier = 1;
+	measure->divider = 1;
 	switch (p->test_vector >> TEST_TYPE_SHIFT) {
 	case TEST_TYPE_PER_LS:
 		writel_relaxed(0x4030D00|BVAL(7, 0, clk_sel), CLK_TEST_REG);
@@ -3355,7 +3355,7 @@
 		writel_relaxed(BVAL(6, 1, clk_sel)|BIT(0), DBG_CFG_REG_LS_REG);
 		break;
 	case TEST_TYPE_MM_HS2X:
-		clk->divider = 2;
+		measure->divider = 2;
 	case TEST_TYPE_MM_HS:
 		writel_relaxed(0x402B800, CLK_TEST_REG);
 		writel_relaxed(BVAL(6, 1, clk_sel)|BIT(0), DBG_CFG_REG_HS_REG);
@@ -3367,8 +3367,8 @@
 		break;
 	case TEST_TYPE_SC:
 		writel_relaxed(0x5020000|BVAL(16, 10, clk_sel), CLK_TEST_REG);
-		clk->sample_ticks = 0x4000;
-		clk->multiplier = 2;
+		measure->sample_ticks = 0x4000;
+		measure->multiplier = 2;
 		break;
 	default:
 		ret = -EPERM;
@@ -3410,7 +3410,7 @@
 	unsigned long flags;
 	u32 pdm_reg_backup, ringosc_reg_backup;
 	u64 raw_count_short, raw_count_full;
-	struct measure_clk *clk = to_measure_clk(c);
+	struct measure_clk *measure = to_measure_clk(c);
 	unsigned ret;
 
 	spin_lock_irqsave(&local_clock_reg_lock, flags);
@@ -3431,7 +3431,7 @@
 	/* Run a short measurement. (~1 ms) */
 	raw_count_short = run_measurement(0x1000);
 	/* Run a full measurement. (~14 ms) */
-	raw_count_full = run_measurement(clk->sample_ticks);
+	raw_count_full = run_measurement(measure->sample_ticks);
 
 	writel_relaxed(ringosc_reg_backup, RINGOSC_NS_REG);
 	writel_relaxed(pdm_reg_backup, PDM_CLK_NS_REG);
@@ -3442,9 +3442,9 @@
 	else {
 		/* Compute rate in Hz. */
 		raw_count_full = ((raw_count_full * 10) + 15) * 4800000;
-		do_div(raw_count_full,
-		       (((clk->sample_ticks * 10) + 35) * clk->divider));
-		ret = (raw_count_full * clk->multiplier);
+		do_div(raw_count_full, (((measure->sample_ticks * 10) + 35)
+			* measure->divider));
+		ret = (raw_count_full * measure->multiplier);
 	}
 
 	/* Route dbg_hs_clk to PLLTEST.  300mV single-ended amplitude. */
@@ -3454,12 +3454,12 @@
 	return ret;
 }
 #else /* !CONFIG_DEBUG_FS */
-static int measure_clk_set_parent(struct clk *clk, struct clk *parent)
+static int measure_clk_set_parent(struct clk *c, struct clk *parent)
 {
 	return -EINVAL;
 }
 
-static unsigned long measure_clk_get_rate(struct clk *clk)
+static unsigned long measure_clk_get_rate(struct clk *c)
 {
 	return 0;
 }
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index a2e0bc9..f7ccb35 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -216,33 +216,33 @@
 
 static DEFINE_SPINLOCK(soft_vote_lock);
 
-static int pll_acpu_vote_clk_enable(struct clk *clk)
+static int pll_acpu_vote_clk_enable(struct clk *c)
 {
 	int ret = 0;
 	unsigned long flags;
-	struct pll_vote_clk *pll = to_pll_vote_clk(clk);
+	struct pll_vote_clk *pllv = to_pll_vote_clk(c);
 
 	spin_lock_irqsave(&soft_vote_lock, flags);
 
-	if (!*pll->soft_vote)
-		ret = pll_vote_clk_enable(clk);
+	if (!*pllv->soft_vote)
+		ret = pll_vote_clk_enable(c);
 	if (ret == 0)
-		*pll->soft_vote |= (pll->soft_vote_mask);
+		*pllv->soft_vote |= (pllv->soft_vote_mask);
 
 	spin_unlock_irqrestore(&soft_vote_lock, flags);
 	return ret;
 }
 
-static void pll_acpu_vote_clk_disable(struct clk *clk)
+static void pll_acpu_vote_clk_disable(struct clk *c)
 {
 	unsigned long flags;
-	struct pll_vote_clk *pll = to_pll_vote_clk(clk);
+	struct pll_vote_clk *pllv = to_pll_vote_clk(c);
 
 	spin_lock_irqsave(&soft_vote_lock, flags);
 
-	*pll->soft_vote &= ~(pll->soft_vote_mask);
-	if (!*pll->soft_vote)
-		pll_vote_clk_disable(clk);
+	*pllv->soft_vote &= ~(pllv->soft_vote_mask);
+	if (!*pllv->soft_vote)
+		pll_vote_clk_disable(c);
 
 	spin_unlock_irqrestore(&soft_vote_lock, flags);
 }
@@ -1376,7 +1376,7 @@
 #ifdef CONFIG_DEBUG_FS
 struct measure_sel {
 	u32 test_vector;
-	struct clk *clk;
+	struct clk *c;
 };
 
 static DEFINE_CLK_MEASURE(q6sw_clk);
@@ -1447,12 +1447,12 @@
 	{ TEST_LPA_HS(0x00), &q6_func_clk },
 };
 
-static struct measure_sel *find_measure_sel(struct clk *clk)
+static struct measure_sel *find_measure_sel(struct clk *c)
 {
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(measure_mux); i++)
-		if (measure_mux[i].clk == clk)
+		if (measure_mux[i].c == c)
 			return &measure_mux[i];
 	return NULL;
 }
@@ -1462,7 +1462,7 @@
 	int ret = 0;
 	u32 clk_sel;
 	struct measure_sel *p;
-	struct measure_clk *clk = to_measure_clk(c);
+	struct measure_clk *measure = to_measure_clk(c);
 	unsigned long flags;
 
 	if (!parent)
@@ -1478,9 +1478,9 @@
 	 * Program the test vector, measurement period (sample_ticks)
 	 * and scaling multiplier.
 	 */
-	clk->sample_ticks = 0x10000;
+	measure->sample_ticks = 0x10000;
 	clk_sel = p->test_vector & TEST_CLK_SEL_MASK;
-	clk->multiplier = 1;
+	measure->multiplier = 1;
 	switch (p->test_vector >> TEST_TYPE_SHIFT) {
 	case TEST_TYPE_PER_LS:
 		writel_relaxed(0x4030D00|BVAL(7, 0, clk_sel), CLK_TEST_REG);
@@ -1539,7 +1539,7 @@
 	unsigned long flags;
 	u32 pdm_reg_backup, ringosc_reg_backup;
 	u64 raw_count_short, raw_count_full;
-	struct measure_clk *clk = to_measure_clk(c);
+	struct measure_clk *measure = to_measure_clk(c);
 	unsigned ret;
 
 	spin_lock_irqsave(&local_clock_reg_lock, flags);
@@ -1560,7 +1560,7 @@
 	/* Run a short measurement. (~1 ms) */
 	raw_count_short = run_measurement(0x1000);
 	/* Run a full measurement. (~14 ms) */
-	raw_count_full = run_measurement(clk->sample_ticks);
+	raw_count_full = run_measurement(measure->sample_ticks);
 
 	writel_relaxed(ringosc_reg_backup, RINGOSC_NS_REG);
 	writel_relaxed(pdm_reg_backup, PDM_CLK_NS_REG);
@@ -1571,8 +1571,8 @@
 	else {
 		/* Compute rate in Hz. */
 		raw_count_full = ((raw_count_full * 10) + 15) * 4800000;
-		do_div(raw_count_full, ((clk->sample_ticks * 10) + 35));
-		ret = (raw_count_full * clk->multiplier);
+		do_div(raw_count_full, ((measure->sample_ticks * 10) + 35));
+		ret = (raw_count_full * measure->multiplier);
 	}
 
 	/* Route dbg_hs_clk to PLLTEST.  300mV single-ended amplitude. */
@@ -1582,12 +1582,12 @@
 	return ret;
 }
 #else /* !CONFIG_DEBUG_FS */
-static int measure_clk_set_parent(struct clk *clk, struct clk *parent)
+static int measure_clk_set_parent(struct clk *c, struct clk *parent)
 {
 	return -EINVAL;
 }
 
-static unsigned long measure_clk_get_rate(struct clk *clk)
+static unsigned long measure_clk_get_rate(struct clk *c)
 {
 	return 0;
 }
diff --git a/arch/arm/mach-msm/clock-copper.c b/arch/arm/mach-msm/clock-copper.c
index 2dadc4c..fcb69f0 100644
--- a/arch/arm/mach-msm/clock-copper.c
+++ b/arch/arm/mach-msm/clock-copper.c
@@ -5017,6 +5017,7 @@
 static void __init msmcopper_clock_post_init(void)
 {
 	clk_set_rate(&axi_clk_src.c, 333330000);
+	clk_set_rate(&ocmemnoc_clk_src.c, 333330000);
 
 	/* Set rates for single-rate clocks. */
 	clk_set_rate(&usb30_master_clk_src.c,
diff --git a/arch/arm/mach-msm/clock-fsm9xxx.c b/arch/arm/mach-msm/clock-fsm9xxx.c
index 13a5b65..c188ba6 100644
--- a/arch/arm/mach-msm/clock-fsm9xxx.c
+++ b/arch/arm/mach-msm/clock-fsm9xxx.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
@@ -24,6 +24,7 @@
 static struct clk_lookup msm_clocks_fsm9xxx[] = {
 	CLK_DUMMY("core_clk",	ADM0_CLK,	"msm_dmov", OFF),
 	CLK_DUMMY("core_clk",	UART1_CLK,	"msm_serial.0", OFF),
+	CLK_DUMMY("core_clk",	UART3_CLK,	"msm_uim.2", OFF),
 	CLK_DUMMY("core_clk",	CE_CLK,		"qce.0", OFF),
 	CLK_DUMMY("core_clk",	CE_CLK,		"qcota.0", OFF),
 	CLK_DUMMY("core_clk",	CE_CLK,		"qcrypto.0", OFF),
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index b5ae4ab..0f9404b 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -53,32 +53,32 @@
  */
 
 /* For clocks with MND dividers. */
-void set_rate_mnd(struct rcg_clk *clk, struct clk_freq_tbl *nf)
+void set_rate_mnd(struct rcg_clk *rcg, struct clk_freq_tbl *nf)
 {
 	uint32_t ns_reg_val, ctl_reg_val;
 
 	/* Assert MND reset. */
-	ns_reg_val = readl_relaxed(clk->ns_reg);
+	ns_reg_val = readl_relaxed(rcg->ns_reg);
 	ns_reg_val |= BIT(7);
-	writel_relaxed(ns_reg_val, clk->ns_reg);
+	writel_relaxed(ns_reg_val, rcg->ns_reg);
 
 	/* Program M and D values. */
-	writel_relaxed(nf->md_val, clk->md_reg);
+	writel_relaxed(nf->md_val, rcg->md_reg);
 
 	/* If the clock has a separate CC register, program it. */
-	if (clk->ns_reg != clk->b.ctl_reg) {
-		ctl_reg_val = readl_relaxed(clk->b.ctl_reg);
-		ctl_reg_val &= ~(clk->ctl_mask);
+	if (rcg->ns_reg != rcg->b.ctl_reg) {
+		ctl_reg_val = readl_relaxed(rcg->b.ctl_reg);
+		ctl_reg_val &= ~(rcg->ctl_mask);
 		ctl_reg_val |= nf->ctl_val;
-		writel_relaxed(ctl_reg_val, clk->b.ctl_reg);
+		writel_relaxed(ctl_reg_val, rcg->b.ctl_reg);
 	}
 
 	/* Deassert MND reset. */
 	ns_reg_val &= ~BIT(7);
-	writel_relaxed(ns_reg_val, clk->ns_reg);
+	writel_relaxed(ns_reg_val, rcg->ns_reg);
 }
 
-void set_rate_nop(struct rcg_clk *clk, struct clk_freq_tbl *nf)
+void set_rate_nop(struct rcg_clk *rcg, struct clk_freq_tbl *nf)
 {
 	/*
 	 * Nothing to do for fixed-rate or integer-divider clocks. Any settings
@@ -88,31 +88,31 @@
 	 */
 }
 
-void set_rate_mnd_8(struct rcg_clk *clk, struct clk_freq_tbl *nf)
+void set_rate_mnd_8(struct rcg_clk *rcg, struct clk_freq_tbl *nf)
 {
 	uint32_t ctl_reg_val;
 
 	/* Assert MND reset. */
-	ctl_reg_val = readl_relaxed(clk->b.ctl_reg);
+	ctl_reg_val = readl_relaxed(rcg->b.ctl_reg);
 	ctl_reg_val |= BIT(8);
-	writel_relaxed(ctl_reg_val, clk->b.ctl_reg);
+	writel_relaxed(ctl_reg_val, rcg->b.ctl_reg);
 
 	/* Program M and D values. */
-	writel_relaxed(nf->md_val, clk->md_reg);
+	writel_relaxed(nf->md_val, rcg->md_reg);
 
 	/* Program MN counter Enable and Mode. */
-	ctl_reg_val &= ~(clk->ctl_mask);
+	ctl_reg_val &= ~(rcg->ctl_mask);
 	ctl_reg_val |= nf->ctl_val;
-	writel_relaxed(ctl_reg_val, clk->b.ctl_reg);
+	writel_relaxed(ctl_reg_val, rcg->b.ctl_reg);
 
 	/* Deassert MND reset. */
 	ctl_reg_val &= ~BIT(8);
-	writel_relaxed(ctl_reg_val, clk->b.ctl_reg);
+	writel_relaxed(ctl_reg_val, rcg->b.ctl_reg);
 }
 
-void set_rate_mnd_banked(struct rcg_clk *clk, struct clk_freq_tbl *nf)
+void set_rate_mnd_banked(struct rcg_clk *rcg, struct clk_freq_tbl *nf)
 {
-	struct bank_masks *banks = clk->bank_info;
+	struct bank_masks *banks = rcg->bank_info;
 	const struct bank_mask_info *new_bank_masks;
 	const struct bank_mask_info *old_bank_masks;
 	uint32_t ns_reg_val, ctl_reg_val;
@@ -123,10 +123,10 @@
 	 * off, program the active bank since bank switching won't work if
 	 * both banks aren't running.
 	 */
-	ctl_reg_val = readl_relaxed(clk->b.ctl_reg);
+	ctl_reg_val = readl_relaxed(rcg->b.ctl_reg);
 	bank_sel = !!(ctl_reg_val & banks->bank_sel_mask);
 	 /* If clock isn't running, don't switch banks. */
-	bank_sel ^= (!clk->enabled || clk->current_freq->freq_hz == 0);
+	bank_sel ^= (!rcg->enabled || rcg->current_freq->freq_hz == 0);
 	if (bank_sel == 0) {
 		new_bank_masks = &banks->bank1_mask;
 		old_bank_masks = &banks->bank0_mask;
@@ -135,46 +135,46 @@
 		old_bank_masks = &banks->bank1_mask;
 	}
 
-	ns_reg_val = readl_relaxed(clk->ns_reg);
+	ns_reg_val = readl_relaxed(rcg->ns_reg);
 
 	/* Assert bank MND reset. */
 	ns_reg_val |= new_bank_masks->rst_mask;
-	writel_relaxed(ns_reg_val, clk->ns_reg);
+	writel_relaxed(ns_reg_val, rcg->ns_reg);
 
 	/*
 	 * Program NS only if the clock is enabled, since the NS will be set
 	 * as part of the enable procedure and should remain with a low-power
 	 * MUX input selected until then.
 	 */
-	if (clk->enabled) {
+	if (rcg->enabled) {
 		ns_reg_val &= ~(new_bank_masks->ns_mask);
 		ns_reg_val |= (nf->ns_val & new_bank_masks->ns_mask);
-		writel_relaxed(ns_reg_val, clk->ns_reg);
+		writel_relaxed(ns_reg_val, rcg->ns_reg);
 	}
 
 	writel_relaxed(nf->md_val, new_bank_masks->md_reg);
 
 	/* Enable counter only if clock is enabled. */
-	if (clk->enabled)
+	if (rcg->enabled)
 		ctl_reg_val |= new_bank_masks->mnd_en_mask;
 	else
 		ctl_reg_val &= ~(new_bank_masks->mnd_en_mask);
 
 	ctl_reg_val &= ~(new_bank_masks->mode_mask);
 	ctl_reg_val |= (nf->ctl_val & new_bank_masks->mode_mask);
-	writel_relaxed(ctl_reg_val, clk->b.ctl_reg);
+	writel_relaxed(ctl_reg_val, rcg->b.ctl_reg);
 
 	/* Deassert bank MND reset. */
 	ns_reg_val &= ~(new_bank_masks->rst_mask);
-	writel_relaxed(ns_reg_val, clk->ns_reg);
+	writel_relaxed(ns_reg_val, rcg->ns_reg);
 
 	/*
 	 * Switch to the new bank if clock is running.  If it isn't, then
 	 * no switch is necessary since we programmed the active bank.
 	 */
-	if (clk->enabled && clk->current_freq->freq_hz) {
+	if (rcg->enabled && rcg->current_freq->freq_hz) {
 		ctl_reg_val ^= banks->bank_sel_mask;
-		writel_relaxed(ctl_reg_val, clk->b.ctl_reg);
+		writel_relaxed(ctl_reg_val, rcg->b.ctl_reg);
 		/*
 		 * Wait at least 6 cycles of slowest bank's clock
 		 * for the glitch-free MUX to fully switch sources.
@@ -184,22 +184,22 @@
 
 		/* Disable old bank's MN counter. */
 		ctl_reg_val &= ~(old_bank_masks->mnd_en_mask);
-		writel_relaxed(ctl_reg_val, clk->b.ctl_reg);
+		writel_relaxed(ctl_reg_val, rcg->b.ctl_reg);
 
 		/* Program old bank to a low-power source and divider. */
 		ns_reg_val &= ~(old_bank_masks->ns_mask);
-		ns_reg_val |= (clk->freq_tbl->ns_val & old_bank_masks->ns_mask);
-		writel_relaxed(ns_reg_val, clk->ns_reg);
+		ns_reg_val |= (rcg->freq_tbl->ns_val & old_bank_masks->ns_mask);
+		writel_relaxed(ns_reg_val, rcg->ns_reg);
 	}
 
 	/* Update the MND_EN and NS masks to match the current bank. */
-	clk->mnd_en_mask = new_bank_masks->mnd_en_mask;
-	clk->ns_mask = new_bank_masks->ns_mask;
+	rcg->mnd_en_mask = new_bank_masks->mnd_en_mask;
+	rcg->ns_mask = new_bank_masks->ns_mask;
 }
 
-void set_rate_div_banked(struct rcg_clk *clk, struct clk_freq_tbl *nf)
+void set_rate_div_banked(struct rcg_clk *rcg, struct clk_freq_tbl *nf)
 {
-	struct bank_masks *banks = clk->bank_info;
+	struct bank_masks *banks = rcg->bank_info;
 	const struct bank_mask_info *new_bank_masks;
 	const struct bank_mask_info *old_bank_masks;
 	uint32_t ns_reg_val, bank_sel;
@@ -209,10 +209,10 @@
 	 * off, program the active bank since bank switching won't work if
 	 * both banks aren't running.
 	 */
-	ns_reg_val = readl_relaxed(clk->ns_reg);
+	ns_reg_val = readl_relaxed(rcg->ns_reg);
 	bank_sel = !!(ns_reg_val & banks->bank_sel_mask);
 	 /* If clock isn't running, don't switch banks. */
-	bank_sel ^= (!clk->enabled || clk->current_freq->freq_hz == 0);
+	bank_sel ^= (!rcg->enabled || rcg->current_freq->freq_hz == 0);
 	if (bank_sel == 0) {
 		new_bank_masks = &banks->bank1_mask;
 		old_bank_masks = &banks->bank0_mask;
@@ -226,19 +226,19 @@
 	 * as part of the enable procedure and should remain with a low-power
 	 * MUX input selected until then.
 	 */
-	if (clk->enabled) {
+	if (rcg->enabled) {
 		ns_reg_val &= ~(new_bank_masks->ns_mask);
 		ns_reg_val |= (nf->ns_val & new_bank_masks->ns_mask);
-		writel_relaxed(ns_reg_val, clk->ns_reg);
+		writel_relaxed(ns_reg_val, rcg->ns_reg);
 	}
 
 	/*
 	 * Switch to the new bank if clock is running.  If it isn't, then
 	 * no switch is necessary since we programmed the active bank.
 	 */
-	if (clk->enabled && clk->current_freq->freq_hz) {
+	if (rcg->enabled && rcg->current_freq->freq_hz) {
 		ns_reg_val ^= banks->bank_sel_mask;
-		writel_relaxed(ns_reg_val, clk->ns_reg);
+		writel_relaxed(ns_reg_val, rcg->ns_reg);
 		/*
 		 * Wait at least 6 cycles of slowest bank's clock
 		 * for the glitch-free MUX to fully switch sources.
@@ -248,12 +248,12 @@
 
 		/* Program old bank to a low-power source and divider. */
 		ns_reg_val &= ~(old_bank_masks->ns_mask);
-		ns_reg_val |= (clk->freq_tbl->ns_val & old_bank_masks->ns_mask);
-		writel_relaxed(ns_reg_val, clk->ns_reg);
+		ns_reg_val |= (rcg->freq_tbl->ns_val & old_bank_masks->ns_mask);
+		writel_relaxed(ns_reg_val, rcg->ns_reg);
 	}
 
 	/* Update the NS mask to match the current bank. */
-	clk->ns_mask = new_bank_masks->ns_mask;
+	rcg->ns_mask = new_bank_masks->ns_mask;
 }
 
 /*
@@ -261,10 +261,10 @@
  */
 
 /* Return non-zero if a clock status registers shows the clock is halted. */
-static int branch_clk_is_halted(const struct branch *clk)
+static int branch_clk_is_halted(const struct branch *b)
 {
-	int invert = (clk->halt_check == ENABLE);
-	int status_bit = readl_relaxed(clk->halt_reg) & BIT(clk->halt_bit);
+	int invert = (b->halt_check == ENABLE);
+	int status_bit = readl_relaxed(b->halt_reg) & BIT(b->halt_bit);
 	return invert ? !status_bit : status_bit;
 }
 
@@ -276,14 +276,14 @@
 	return !!(readl_relaxed(b->hwcg_reg) & b->hwcg_mask);
 }
 
-void __branch_clk_enable_reg(const struct branch *clk, const char *name)
+void __branch_enable_reg(const struct branch *b, const char *name)
 {
 	u32 reg_val;
 
-	if (clk->en_mask) {
-		reg_val = readl_relaxed(clk->ctl_reg);
-		reg_val |= clk->en_mask;
-		writel_relaxed(reg_val, clk->ctl_reg);
+	if (b->en_mask) {
+		reg_val = readl_relaxed(b->ctl_reg);
+		reg_val |= b->en_mask;
+		writel_relaxed(reg_val, b->ctl_reg);
 	}
 
 	/*
@@ -295,19 +295,19 @@
 	mb();
 
 	/* Skip checking halt bit if the clock is in hardware gated mode */
-	if (branch_in_hwcg_mode(clk))
+	if (branch_in_hwcg_mode(b))
 		return;
 
 	/* Wait for clock to enable before returning. */
-	if (clk->halt_check == DELAY)
+	if (b->halt_check == DELAY) {
 		udelay(HALT_CHECK_DELAY_US);
-	else if (clk->halt_check == ENABLE || clk->halt_check == HALT
-			|| clk->halt_check == ENABLE_VOTED
-			|| clk->halt_check == HALT_VOTED) {
+	} else if (b->halt_check == ENABLE || b->halt_check == HALT
+			|| b->halt_check == ENABLE_VOTED
+			|| b->halt_check == HALT_VOTED) {
 		int count;
 
 		/* Wait up to HALT_CHECK_MAX_LOOPS for clock to enable. */
-		for (count = HALT_CHECK_MAX_LOOPS; branch_clk_is_halted(clk)
+		for (count = HALT_CHECK_MAX_LOOPS; branch_clk_is_halted(b)
 					&& count > 0; count--)
 			udelay(1);
 		WARN(count == 0, "%s status stuck at 'off'", name);
@@ -315,50 +315,50 @@
 }
 
 /* Perform any register operations required to enable the clock. */
-static void __rcg_clk_enable_reg(struct rcg_clk *clk)
+static void __rcg_clk_enable_reg(struct rcg_clk *rcg)
 {
 	u32 reg_val;
-	void __iomem *const reg = clk->b.ctl_reg;
+	void __iomem *const reg = rcg->b.ctl_reg;
 
-	WARN(clk->current_freq == &rcg_dummy_freq,
+	WARN(rcg->current_freq == &rcg_dummy_freq,
 		"Attempting to enable %s before setting its rate. "
-		"Set the rate first!\n", clk->c.dbg_name);
+		"Set the rate first!\n", rcg->c.dbg_name);
 
 	/*
 	 * Program the NS register, if applicable. NS registers are not
 	 * set in the set_rate path because power can be saved by deferring
 	 * the selection of a clocked source until the clock is enabled.
 	 */
-	if (clk->ns_mask) {
-		reg_val = readl_relaxed(clk->ns_reg);
-		reg_val &= ~(clk->ns_mask);
-		reg_val |= (clk->current_freq->ns_val & clk->ns_mask);
-		writel_relaxed(reg_val, clk->ns_reg);
+	if (rcg->ns_mask) {
+		reg_val = readl_relaxed(rcg->ns_reg);
+		reg_val &= ~(rcg->ns_mask);
+		reg_val |= (rcg->current_freq->ns_val & rcg->ns_mask);
+		writel_relaxed(reg_val, rcg->ns_reg);
 	}
 
 	/* Enable MN counter, if applicable. */
 	reg_val = readl_relaxed(reg);
-	if (clk->current_freq->md_val) {
-		reg_val |= clk->mnd_en_mask;
+	if (rcg->current_freq->md_val) {
+		reg_val |= rcg->mnd_en_mask;
 		writel_relaxed(reg_val, reg);
 	}
 	/* Enable root. */
-	if (clk->root_en_mask) {
-		reg_val |= clk->root_en_mask;
+	if (rcg->root_en_mask) {
+		reg_val |= rcg->root_en_mask;
 		writel_relaxed(reg_val, reg);
 	}
-	__branch_clk_enable_reg(&clk->b, clk->c.dbg_name);
+	__branch_enable_reg(&rcg->b, rcg->c.dbg_name);
 }
 
 /* Perform any register operations required to disable the branch. */
-u32 __branch_clk_disable_reg(const struct branch *clk, const char *name)
+u32 __branch_disable_reg(const struct branch *b, const char *name)
 {
 	u32 reg_val;
 
-	reg_val = readl_relaxed(clk->ctl_reg);
-	if (clk->en_mask) {
-		reg_val &= ~(clk->en_mask);
-		writel_relaxed(reg_val, clk->ctl_reg);
+	reg_val = readl_relaxed(b->ctl_reg);
+	if (b->en_mask) {
+		reg_val &= ~(b->en_mask);
+		writel_relaxed(reg_val, b->ctl_reg);
 	}
 
 	/*
@@ -370,18 +370,18 @@
 	mb();
 
 	/* Skip checking halt bit if the clock is in hardware gated mode */
-	if (branch_in_hwcg_mode(clk))
+	if (branch_in_hwcg_mode(b))
 		return reg_val;
 
 	/* Wait for clock to disable before continuing. */
-	if (clk->halt_check == DELAY || clk->halt_check == ENABLE_VOTED
-				     || clk->halt_check == HALT_VOTED)
+	if (b->halt_check == DELAY || b->halt_check == ENABLE_VOTED
+				   || b->halt_check == HALT_VOTED) {
 		udelay(HALT_CHECK_DELAY_US);
-	else if (clk->halt_check == ENABLE || clk->halt_check == HALT) {
+	} else if (b->halt_check == ENABLE || b->halt_check == HALT) {
 		int count;
 
 		/* Wait up to HALT_CHECK_MAX_LOOPS for clock to disable. */
-		for (count = HALT_CHECK_MAX_LOOPS; !branch_clk_is_halted(clk)
+		for (count = HALT_CHECK_MAX_LOOPS; !branch_clk_is_halted(b)
 					&& count > 0; count--)
 			udelay(1);
 		WARN(count == 0, "%s status stuck at 'on'", name);
@@ -391,31 +391,31 @@
 }
 
 /* Perform any register operations required to disable the generator. */
-static void __rcg_clk_disable_reg(struct rcg_clk *clk)
+static void __rcg_clk_disable_reg(struct rcg_clk *rcg)
 {
-	void __iomem *const reg = clk->b.ctl_reg;
+	void __iomem *const reg = rcg->b.ctl_reg;
 	uint32_t reg_val;
 
-	reg_val = __branch_clk_disable_reg(&clk->b, clk->c.dbg_name);
+	reg_val = __branch_disable_reg(&rcg->b, rcg->c.dbg_name);
 	/* Disable root. */
-	if (clk->root_en_mask) {
-		reg_val &= ~(clk->root_en_mask);
+	if (rcg->root_en_mask) {
+		reg_val &= ~(rcg->root_en_mask);
 		writel_relaxed(reg_val, reg);
 	}
 	/* Disable MN counter, if applicable. */
-	if (clk->current_freq->md_val) {
-		reg_val &= ~(clk->mnd_en_mask);
+	if (rcg->current_freq->md_val) {
+		reg_val &= ~(rcg->mnd_en_mask);
 		writel_relaxed(reg_val, reg);
 	}
 	/*
 	 * Program NS register to low-power value with an un-clocked or
 	 * slowly-clocked source selected.
 	 */
-	if (clk->ns_mask) {
-		reg_val = readl_relaxed(clk->ns_reg);
-		reg_val &= ~(clk->ns_mask);
-		reg_val |= (clk->freq_tbl->ns_val & clk->ns_mask);
-		writel_relaxed(reg_val, clk->ns_reg);
+	if (rcg->ns_mask) {
+		reg_val = readl_relaxed(rcg->ns_reg);
+		reg_val &= ~(rcg->ns_mask);
+		reg_val |= (rcg->freq_tbl->ns_val & rcg->ns_mask);
+		writel_relaxed(reg_val, rcg->ns_reg);
 	}
 }
 
@@ -423,11 +423,11 @@
 static int rcg_clk_enable(struct clk *c)
 {
 	unsigned long flags;
-	struct rcg_clk *clk = to_rcg_clk(c);
+	struct rcg_clk *rcg = to_rcg_clk(c);
 
 	spin_lock_irqsave(&local_clock_reg_lock, flags);
-	__rcg_clk_enable_reg(clk);
-	clk->enabled = true;
+	__rcg_clk_enable_reg(rcg);
+	rcg->enabled = true;
 	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
 
 	return 0;
@@ -437,11 +437,11 @@
 static void rcg_clk_disable(struct clk *c)
 {
 	unsigned long flags;
-	struct rcg_clk *clk = to_rcg_clk(c);
+	struct rcg_clk *rcg = to_rcg_clk(c);
 
 	spin_lock_irqsave(&local_clock_reg_lock, flags);
-	__rcg_clk_disable_reg(clk);
-	clk->enabled = false;
+	__rcg_clk_disable_reg(rcg);
+	rcg->enabled = false;
 	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
 }
 
@@ -452,21 +452,21 @@
 /* Set a clock to an exact rate. */
 static int rcg_clk_set_rate(struct clk *c, unsigned long rate)
 {
-	struct rcg_clk *clk = to_rcg_clk(c);
+	struct rcg_clk *rcg = to_rcg_clk(c);
 	struct clk_freq_tbl *nf, *cf;
 	struct clk *chld;
 	int rc = 0;
 
-	for (nf = clk->freq_tbl; nf->freq_hz != FREQ_END
+	for (nf = rcg->freq_tbl; nf->freq_hz != FREQ_END
 			&& nf->freq_hz != rate; nf++)
 		;
 
 	if (nf->freq_hz == FREQ_END)
 		return -EINVAL;
 
-	cf = clk->current_freq;
+	cf = rcg->current_freq;
 
-	if (clk->enabled) {
+	if (rcg->enabled) {
 		/* Enable source clock dependency for the new freq. */
 		rc = clk_enable(nf->src_clk);
 		if (rc)
@@ -476,9 +476,9 @@
 	spin_lock(&local_clock_reg_lock);
 
 	/* Disable branch if clock isn't dual-banked with a glitch-free MUX. */
-	if (!clk->bank_info) {
+	if (!rcg->bank_info) {
 		/* Disable all branches to prevent glitches. */
-		list_for_each_entry(chld, &clk->c.children, siblings) {
+		list_for_each_entry(chld, &rcg->c.children, siblings) {
 			struct branch_clk *x = to_branch_clk(chld);
 			/*
 			 * We don't need to grab the child's lock because
@@ -486,56 +486,56 @@
 			 * only modified within lock.
 			 */
 			if (x->enabled)
-				__branch_clk_disable_reg(&x->b, x->c.dbg_name);
+				__branch_disable_reg(&x->b, x->c.dbg_name);
 		}
-		if (clk->enabled)
-			__rcg_clk_disable_reg(clk);
+		if (rcg->enabled)
+			__rcg_clk_disable_reg(rcg);
 	}
 
 	/* Perform clock-specific frequency switch operations. */
-	BUG_ON(!clk->set_rate);
-	clk->set_rate(clk, nf);
+	BUG_ON(!rcg->set_rate);
+	rcg->set_rate(rcg, nf);
 
 	/*
 	 * Current freq must be updated before __rcg_clk_enable_reg()
 	 * is called to make sure the MNCNTR_EN bit is set correctly.
 	 */
-	clk->current_freq = nf;
+	rcg->current_freq = nf;
 
 	/* Enable any clocks that were disabled. */
-	if (!clk->bank_info) {
-		if (clk->enabled)
-			__rcg_clk_enable_reg(clk);
+	if (!rcg->bank_info) {
+		if (rcg->enabled)
+			__rcg_clk_enable_reg(rcg);
 		/* Enable only branches that were ON before. */
-		list_for_each_entry(chld, &clk->c.children, siblings) {
+		list_for_each_entry(chld, &rcg->c.children, siblings) {
 			struct branch_clk *x = to_branch_clk(chld);
 			if (x->enabled)
-				__branch_clk_enable_reg(&x->b, x->c.dbg_name);
+				__branch_enable_reg(&x->b, x->c.dbg_name);
 		}
 	}
 
 	spin_unlock(&local_clock_reg_lock);
 
 	/* Release source requirements of the old freq. */
-	if (clk->enabled)
+	if (rcg->enabled)
 		clk_disable(cf->src_clk);
 
 	return rc;
 }
 
 /* Check if a clock is currently enabled. */
-static int rcg_clk_is_enabled(struct clk *clk)
+static int rcg_clk_is_enabled(struct clk *c)
 {
-	return to_rcg_clk(clk)->enabled;
+	return to_rcg_clk(c)->enabled;
 }
 
 /* Return a supported rate that's at least the specified rate. */
 static long rcg_clk_round_rate(struct clk *c, unsigned long rate)
 {
-	struct rcg_clk *clk = to_rcg_clk(c);
+	struct rcg_clk *rcg = to_rcg_clk(c);
 	struct clk_freq_tbl *f;
 
-	for (f = clk->freq_tbl; f->freq_hz != FREQ_END; f++)
+	for (f = rcg->freq_tbl; f->freq_hz != FREQ_END; f++)
 		if (f->freq_hz >= rate)
 			return f->freq_hz;
 
@@ -545,26 +545,26 @@
 /* Return the nth supported frequency for a given clock. */
 static int rcg_clk_list_rate(struct clk *c, unsigned n)
 {
-	struct rcg_clk *clk = to_rcg_clk(c);
+	struct rcg_clk *rcg = to_rcg_clk(c);
 
-	if (!clk->freq_tbl || clk->freq_tbl->freq_hz == FREQ_END)
+	if (!rcg->freq_tbl || rcg->freq_tbl->freq_hz == FREQ_END)
 		return -ENXIO;
 
-	return (clk->freq_tbl + n)->freq_hz;
+	return (rcg->freq_tbl + n)->freq_hz;
 }
 
-static struct clk *rcg_clk_get_parent(struct clk *clk)
+static struct clk *rcg_clk_get_parent(struct clk *c)
 {
-	return to_rcg_clk(clk)->current_freq->src_clk;
+	return to_rcg_clk(c)->current_freq->src_clk;
 }
 
 /* Disable hw clock gating if not set at boot */
-enum handoff branch_handoff(struct branch *clk, struct clk *c)
+enum handoff branch_handoff(struct branch *b, struct clk *c)
 {
-	if (!branch_in_hwcg_mode(clk)) {
-		clk->hwcg_mask = 0;
+	if (!branch_in_hwcg_mode(b)) {
+		b->hwcg_mask = 0;
 		c->flags &= ~CLKFLAG_HWCG;
-		if (readl_relaxed(clk->ctl_reg) & clk->en_mask)
+		if (readl_relaxed(b->ctl_reg) & b->en_mask)
 			return HANDOFF_ENABLED_CLK;
 	} else {
 		c->flags |= CLKFLAG_HWCG;
@@ -574,24 +574,24 @@
 
 static enum handoff branch_clk_handoff(struct clk *c)
 {
-	struct branch_clk *clk = to_branch_clk(c);
-	return branch_handoff(&clk->b, &clk->c);
+	struct branch_clk *br = to_branch_clk(c);
+	return branch_handoff(&br->b, &br->c);
 }
 
 static enum handoff rcg_clk_handoff(struct clk *c)
 {
-	struct rcg_clk *clk = to_rcg_clk(c);
+	struct rcg_clk *rcg = to_rcg_clk(c);
 	uint32_t ctl_val, ns_val, md_val, ns_mask;
 	struct clk_freq_tbl *freq;
 	enum handoff ret;
 
-	ctl_val = readl_relaxed(clk->b.ctl_reg);
-	ret = branch_handoff(&clk->b, &clk->c);
+	ctl_val = readl_relaxed(rcg->b.ctl_reg);
+	ret = branch_handoff(&rcg->b, &rcg->c);
 	if (ret == HANDOFF_DISABLED_CLK)
 		return HANDOFF_DISABLED_CLK;
 
-	if (clk->bank_info) {
-		const struct bank_masks *bank_masks = clk->bank_info;
+	if (rcg->bank_info) {
+		const struct bank_masks *bank_masks = rcg->bank_info;
 		const struct bank_mask_info *bank_info;
 		if (!(ctl_val & bank_masks->bank_sel_mask))
 			bank_info = &bank_masks->bank0_mask;
@@ -602,13 +602,13 @@
 		md_val = bank_info->md_reg ?
 				readl_relaxed(bank_info->md_reg) : 0;
 	} else {
-		ns_mask = clk->ns_mask;
-		md_val = clk->md_reg ? readl_relaxed(clk->md_reg) : 0;
+		ns_mask = rcg->ns_mask;
+		md_val = rcg->md_reg ? readl_relaxed(rcg->md_reg) : 0;
 	}
 	if (!ns_mask)
 		return HANDOFF_UNKNOWN_RATE;
-	ns_val = readl_relaxed(clk->ns_reg) & ns_mask;
-	for (freq = clk->freq_tbl; freq->freq_hz != FREQ_END; freq++) {
+	ns_val = readl_relaxed(rcg->ns_reg) & ns_mask;
+	for (freq = rcg->freq_tbl; freq->freq_hz != FREQ_END; freq++) {
 		if ((freq->ns_val & ns_mask) == ns_val &&
 		    (!freq->md_val || freq->md_val == md_val))
 			break;
@@ -616,7 +616,7 @@
 	if (freq->freq_hz == FREQ_END)
 		return HANDOFF_UNKNOWN_RATE;
 
-	clk->current_freq = freq;
+	rcg->current_freq = freq;
 	c->rate = freq->freq_hz;
 
 	return HANDOFF_ENABLED_CLK;
@@ -632,40 +632,38 @@
 	},
 };
 
-static int branch_clk_enable(struct clk *clk)
+static int branch_clk_enable(struct clk *c)
 {
 	unsigned long flags;
-	struct branch_clk *branch = to_branch_clk(clk);
+	struct branch_clk *br = to_branch_clk(c);
 
 	spin_lock_irqsave(&local_clock_reg_lock, flags);
-	__branch_clk_enable_reg(&branch->b, branch->c.dbg_name);
-	branch->enabled = true;
+	__branch_enable_reg(&br->b, br->c.dbg_name);
+	br->enabled = true;
 	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
 
 	return 0;
 }
 
-static void branch_clk_disable(struct clk *clk)
+static void branch_clk_disable(struct clk *c)
 {
 	unsigned long flags;
-	struct branch_clk *branch = to_branch_clk(clk);
+	struct branch_clk *br = to_branch_clk(c);
 
 	spin_lock_irqsave(&local_clock_reg_lock, flags);
-	__branch_clk_disable_reg(&branch->b, branch->c.dbg_name);
-	branch->enabled = false;
+	__branch_disable_reg(&br->b, br->c.dbg_name);
+	br->enabled = false;
 	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
 }
 
-static struct clk *branch_clk_get_parent(struct clk *clk)
+static struct clk *branch_clk_get_parent(struct clk *c)
 {
-	struct branch_clk *branch = to_branch_clk(clk);
-	return branch->parent;
+	return to_branch_clk(c)->parent;
 }
 
-static int branch_clk_is_enabled(struct clk *clk)
+static int branch_clk_is_enabled(struct clk *c)
 {
-	struct branch_clk *branch = to_branch_clk(clk);
-	return branch->enabled;
+	return to_branch_clk(c)->enabled;
 }
 
 static void branch_enable_hwcg(struct branch *b)
@@ -692,16 +690,14 @@
 	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
 }
 
-static void branch_clk_enable_hwcg(struct clk *clk)
+static void branch_clk_enable_hwcg(struct clk *c)
 {
-	struct branch_clk *branch = to_branch_clk(clk);
-	branch_enable_hwcg(&branch->b);
+	branch_enable_hwcg(&to_branch_clk(c)->b);
 }
 
-static void branch_clk_disable_hwcg(struct clk *clk)
+static void branch_clk_disable_hwcg(struct clk *c)
 {
-	struct branch_clk *branch = to_branch_clk(clk);
-	branch_disable_hwcg(&branch->b);
+	branch_disable_hwcg(&to_branch_clk(c)->b);
 }
 
 static int branch_set_flags(struct branch *b, unsigned flags)
@@ -738,26 +734,22 @@
 
 static int branch_clk_in_hwcg_mode(struct clk *c)
 {
-	struct branch_clk *clk = to_branch_clk(c);
-	return branch_in_hwcg_mode(&clk->b);
+	return branch_in_hwcg_mode(&to_branch_clk(c)->b);
 }
 
-static void rcg_clk_enable_hwcg(struct clk *clk)
+static void rcg_clk_enable_hwcg(struct clk *c)
 {
-	struct rcg_clk *rcg = to_rcg_clk(clk);
-	branch_enable_hwcg(&rcg->b);
+	branch_enable_hwcg(&to_rcg_clk(c)->b);
 }
 
-static void rcg_clk_disable_hwcg(struct clk *clk)
+static void rcg_clk_disable_hwcg(struct clk *c)
 {
-	struct rcg_clk *rcg = to_rcg_clk(clk);
-	branch_disable_hwcg(&rcg->b);
+	branch_disable_hwcg(&to_rcg_clk(c)->b);
 }
 
 static int rcg_clk_in_hwcg_mode(struct clk *c)
 {
-	struct rcg_clk *clk = to_rcg_clk(c);
-	return branch_in_hwcg_mode(&clk->b);
+	return branch_in_hwcg_mode(&to_rcg_clk(c)->b);
 }
 
 static int rcg_clk_set_flags(struct clk *clk, unsigned flags)
@@ -802,9 +794,9 @@
 	return ret;
 }
 
-static int branch_clk_reset(struct clk *clk, enum clk_reset_action action)
+static int branch_clk_reset(struct clk *c, enum clk_reset_action action)
 {
-	return branch_reset(&to_branch_clk(clk)->b, action);
+	return branch_reset(&to_branch_clk(c)->b, action);
 }
 
 struct clk_ops clk_ops_branch = {
@@ -825,9 +817,9 @@
 	.reset = branch_clk_reset,
 };
 
-static int rcg_clk_reset(struct clk *clk, enum clk_reset_action action)
+static int rcg_clk_reset(struct clk *c, enum clk_reset_action action)
 {
-	return branch_reset(&to_rcg_clk(clk)->b, action);
+	return branch_reset(&to_rcg_clk(c)->b, action);
 }
 
 struct clk_ops clk_ops_rcg = {
@@ -850,10 +842,10 @@
 static int cdiv_clk_enable(struct clk *c)
 {
 	unsigned long flags;
-	struct cdiv_clk *clk = to_cdiv_clk(c);
+	struct cdiv_clk *cdiv = to_cdiv_clk(c);
 
 	spin_lock_irqsave(&local_clock_reg_lock, flags);
-	__branch_clk_enable_reg(&clk->b, clk->c.dbg_name);
+	__branch_enable_reg(&cdiv->b, cdiv->c.dbg_name);
 	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
 
 	return 0;
@@ -862,70 +854,67 @@
 static void cdiv_clk_disable(struct clk *c)
 {
 	unsigned long flags;
-	struct cdiv_clk *clk = to_cdiv_clk(c);
+	struct cdiv_clk *cdiv = to_cdiv_clk(c);
 
 	spin_lock_irqsave(&local_clock_reg_lock, flags);
-	__branch_clk_disable_reg(&clk->b, clk->c.dbg_name);
+	__branch_disable_reg(&cdiv->b, cdiv->c.dbg_name);
 	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
 }
 
 static int cdiv_clk_set_rate(struct clk *c, unsigned long rate)
 {
-	struct cdiv_clk *clk = to_cdiv_clk(c);
+	struct cdiv_clk *cdiv = to_cdiv_clk(c);
 	u32 reg_val;
 
-	if (rate > clk->max_div)
+	if (rate > cdiv->max_div)
 		return -EINVAL;
 
 	spin_lock(&local_clock_reg_lock);
-	reg_val = readl_relaxed(clk->ns_reg);
-	reg_val &= ~(clk->ext_mask | (clk->max_div - 1) << clk->div_offset);
+	reg_val = readl_relaxed(cdiv->ns_reg);
+	reg_val &= ~(cdiv->ext_mask | (cdiv->max_div - 1) << cdiv->div_offset);
 	/* Non-zero rates mean set a divider, zero means use external input */
 	if (rate)
-		reg_val |= (rate - 1) << clk->div_offset;
+		reg_val |= (rate - 1) << cdiv->div_offset;
 	else
-		reg_val |= clk->ext_mask;
-	writel_relaxed(reg_val, clk->ns_reg);
+		reg_val |= cdiv->ext_mask;
+	writel_relaxed(reg_val, cdiv->ns_reg);
 	spin_unlock(&local_clock_reg_lock);
 
-	clk->cur_div = rate;
+	cdiv->cur_div = rate;
 	return 0;
 }
 
 static unsigned long cdiv_clk_get_rate(struct clk *c)
 {
-	struct cdiv_clk *clk = to_cdiv_clk(c);
-	return clk->cur_div;
+	return to_cdiv_clk(c)->cur_div;
 }
 
 static long cdiv_clk_round_rate(struct clk *c, unsigned long rate)
 {
-	struct cdiv_clk *clk = to_cdiv_clk(c);
-	return rate > clk->max_div ? -EPERM : rate;
+	return rate > to_cdiv_clk(c)->max_div ? -EPERM : rate;
 }
 
 static int cdiv_clk_list_rate(struct clk *c, unsigned n)
 {
-	struct cdiv_clk *clk = to_cdiv_clk(c);
-	return n > clk->max_div ? -ENXIO : n;
+	return n > to_cdiv_clk(c)->max_div ? -ENXIO : n;
 }
 
 static enum handoff cdiv_clk_handoff(struct clk *c)
 {
-	struct cdiv_clk *clk = to_cdiv_clk(c);
+	struct cdiv_clk *cdiv = to_cdiv_clk(c);
 	enum handoff ret;
 	u32 reg_val;
 
-	ret = branch_handoff(&clk->b, &clk->c);
+	ret = branch_handoff(&cdiv->b, &cdiv->c);
 	if (ret == HANDOFF_DISABLED_CLK)
 		return ret;
 
-	reg_val = readl_relaxed(clk->ns_reg);
-	if (reg_val & clk->ext_mask) {
-		clk->cur_div = 0;
+	reg_val = readl_relaxed(cdiv->ns_reg);
+	if (reg_val & cdiv->ext_mask) {
+		cdiv->cur_div = 0;
 	} else {
-		reg_val >>= clk->div_offset;
-		clk->cur_div = (reg_val & (clk->max_div - 1)) + 1;
+		reg_val >>= cdiv->div_offset;
+		cdiv->cur_div = (reg_val & (cdiv->max_div - 1)) + 1;
 	}
 
 	return HANDOFF_ENABLED_CLK;
@@ -933,20 +922,17 @@
 
 static void cdiv_clk_enable_hwcg(struct clk *c)
 {
-	struct cdiv_clk *clk = to_cdiv_clk(c);
-	branch_enable_hwcg(&clk->b);
+	branch_enable_hwcg(&to_cdiv_clk(c)->b);
 }
 
 static void cdiv_clk_disable_hwcg(struct clk *c)
 {
-	struct cdiv_clk *clk = to_cdiv_clk(c);
-	branch_disable_hwcg(&clk->b);
+	branch_disable_hwcg(&to_cdiv_clk(c)->b);
 }
 
 static int cdiv_clk_in_hwcg_mode(struct clk *c)
 {
-	struct cdiv_clk *clk = to_cdiv_clk(c);
-	return branch_in_hwcg_mode(&clk->b);
+	return branch_in_hwcg_mode(&to_cdiv_clk(c)->b);
 }
 
 struct clk_ops clk_ops_cdiv = {
diff --git a/arch/arm/mach-msm/clock-local.h b/arch/arm/mach-msm/clock-local.h
index ffc7057..034e09c 100644
--- a/arch/arm/mach-msm/clock-local.h
+++ b/arch/arm/mach-msm/clock-local.h
@@ -156,9 +156,9 @@
 extern struct clk_ops clk_ops_reset;
 
 int branch_reset(struct branch *b, enum clk_reset_action action);
-void __branch_clk_enable_reg(const struct branch *clk, const char *name);
-u32 __branch_clk_disable_reg(const struct branch *clk, const char *name);
-enum handoff branch_handoff(struct branch *clk, struct clk *c);
+void __branch_enable_reg(const struct branch *b, const char *name);
+u32 __branch_disable_reg(const struct branch *b, const char *name);
+enum handoff branch_handoff(struct branch *b, struct clk *c);
 
 /*
  * Generic clock-definition struct and macros
@@ -183,9 +183,9 @@
 	struct clk	c;
 };
 
-static inline struct rcg_clk *to_rcg_clk(struct clk *clk)
+static inline struct rcg_clk *to_rcg_clk(struct clk *c)
 {
-	return container_of(clk, struct rcg_clk, c);
+	return container_of(c, struct rcg_clk, c);
 }
 
 extern struct clk_ops clk_ops_rcg;
@@ -214,9 +214,9 @@
 	struct clk c;
 };
 
-static inline struct cdiv_clk *to_cdiv_clk(struct clk *clk)
+static inline struct cdiv_clk *to_cdiv_clk(struct clk *c)
 {
-	return container_of(clk, struct cdiv_clk, c);
+	return container_of(c, struct cdiv_clk, c);
 }
 
 extern struct clk_ops clk_ops_cdiv;
@@ -234,7 +234,7 @@
  * @enabled: true if clock is on, false otherwise
  * @b: branch
  * @parent: clock source
- * @c: clk
+ * @c: clock
  *
  * An on/off switch with a rate derived from the parent.
  */
@@ -245,9 +245,9 @@
 	struct clk c;
 };
 
-static inline struct branch_clk *to_branch_clk(struct clk *clk)
+static inline struct branch_clk *to_branch_clk(struct clk *c)
 {
-	return container_of(clk, struct branch_clk, c);
+	return container_of(c, struct branch_clk, c);
 }
 
 /**
@@ -255,7 +255,7 @@
  * @sample_ticks: sample period in reference clock ticks
  * @multiplier: measurement scale-up factor
  * @divider: measurement scale-down factor
- * @c: clk
+ * @c: clock
 */
 struct measure_clk {
 	u64 sample_ticks;
@@ -266,9 +266,9 @@
 
 extern struct clk_ops clk_ops_empty;
 
-static inline struct measure_clk *to_measure_clk(struct clk *clk)
+static inline struct measure_clk *to_measure_clk(struct clk *c)
 {
-	return container_of(clk, struct measure_clk, c);
+	return container_of(c, struct measure_clk, c);
 }
 
 /*
@@ -280,11 +280,11 @@
 /*
  * Generic set-rate implementations
  */
-void set_rate_mnd(struct rcg_clk *clk, struct clk_freq_tbl *nf);
-void set_rate_nop(struct rcg_clk *clk, struct clk_freq_tbl *nf);
-void set_rate_mnd_8(struct rcg_clk *clk, struct clk_freq_tbl *nf);
-void set_rate_mnd_banked(struct rcg_clk *clk, struct clk_freq_tbl *nf);
-void set_rate_div_banked(struct rcg_clk *clk, struct clk_freq_tbl *nf);
+void set_rate_mnd(struct rcg_clk *rcg, struct clk_freq_tbl *nf);
+void set_rate_nop(struct rcg_clk *rcg, struct clk_freq_tbl *nf);
+void set_rate_mnd_8(struct rcg_clk *rcg, struct clk_freq_tbl *nf);
+void set_rate_mnd_banked(struct rcg_clk *rcg, struct clk_freq_tbl *nf);
+void set_rate_div_banked(struct rcg_clk *rcg, struct clk_freq_tbl *nf);
 
 #endif /* __ARCH_ARM_MACH_MSM_CLOCK_LOCAL_H */
 
diff --git a/arch/arm/mach-msm/clock-pll.c b/arch/arm/mach-msm/clock-pll.c
index d839911..49bb063 100644
--- a/arch/arm/mach-msm/clock-pll.c
+++ b/arch/arm/mach-msm/clock-pll.c
@@ -55,16 +55,16 @@
 
 #define ENABLE_WAIT_MAX_LOOPS 200
 
-int pll_vote_clk_enable(struct clk *clk)
+int pll_vote_clk_enable(struct clk *c)
 {
 	u32 ena, count;
 	unsigned long flags;
-	struct pll_vote_clk *pll = to_pll_vote_clk(clk);
+	struct pll_vote_clk *pllv = to_pll_vote_clk(c);
 
 	spin_lock_irqsave(&pll_reg_lock, flags);
-	ena = readl_relaxed(PLL_EN_REG(pll));
-	ena |= pll->en_mask;
-	writel_relaxed(ena, PLL_EN_REG(pll));
+	ena = readl_relaxed(PLL_EN_REG(pllv));
+	ena |= pllv->en_mask;
+	writel_relaxed(ena, PLL_EN_REG(pllv));
 	spin_unlock_irqrestore(&pll_reg_lock, flags);
 
 	/*
@@ -75,45 +75,44 @@
 
 	/* Wait for pll to enable. */
 	for (count = ENABLE_WAIT_MAX_LOOPS; count > 0; count--) {
-		if (readl_relaxed(PLL_STATUS_REG(pll)) & pll->status_mask)
+		if (readl_relaxed(PLL_STATUS_REG(pllv)) & pllv->status_mask)
 			return 0;
 		udelay(1);
 	}
 
-	WARN("PLL %s didn't enable after voting for it!\n", clk->dbg_name);
+	WARN("PLL %s didn't enable after voting for it!\n", c->dbg_name);
 
 	return -ETIMEDOUT;
 }
 
-void pll_vote_clk_disable(struct clk *clk)
+void pll_vote_clk_disable(struct clk *c)
 {
 	u32 ena;
 	unsigned long flags;
-	struct pll_vote_clk *pll = to_pll_vote_clk(clk);
+	struct pll_vote_clk *pllv = to_pll_vote_clk(c);
 
 	spin_lock_irqsave(&pll_reg_lock, flags);
-	ena = readl_relaxed(PLL_EN_REG(pll));
-	ena &= ~(pll->en_mask);
-	writel_relaxed(ena, PLL_EN_REG(pll));
+	ena = readl_relaxed(PLL_EN_REG(pllv));
+	ena &= ~(pllv->en_mask);
+	writel_relaxed(ena, PLL_EN_REG(pllv));
 	spin_unlock_irqrestore(&pll_reg_lock, flags);
 }
 
-struct clk *pll_vote_clk_get_parent(struct clk *clk)
+struct clk *pll_vote_clk_get_parent(struct clk *c)
 {
-	struct pll_vote_clk *pll = to_pll_vote_clk(clk);
-	return pll->parent;
+	return to_pll_vote_clk(c)->parent;
 }
 
-int pll_vote_clk_is_enabled(struct clk *clk)
+int pll_vote_clk_is_enabled(struct clk *c)
 {
-	struct pll_vote_clk *pll = to_pll_vote_clk(clk);
-	return !!(readl_relaxed(PLL_STATUS_REG(pll)) & pll->status_mask);
+	struct pll_vote_clk *pllv = to_pll_vote_clk(c);
+	return !!(readl_relaxed(PLL_STATUS_REG(pllv)) & pllv->status_mask);
 }
 
-static enum handoff pll_vote_clk_handoff(struct clk *clk)
+static enum handoff pll_vote_clk_handoff(struct clk *c)
 {
-	struct pll_vote_clk *pll = to_pll_vote_clk(clk);
-	if (readl_relaxed(PLL_EN_REG(pll)) & pll->en_mask)
+	struct pll_vote_clk *pllv = to_pll_vote_clk(c);
+	if (readl_relaxed(PLL_EN_REG(pllv)) & pllv->en_mask)
 		return HANDOFF_ENABLED_CLK;
 
 	return HANDOFF_DISABLED_CLK;
@@ -158,10 +157,10 @@
 	mb();
 }
 
-static int local_pll_clk_enable(struct clk *clk)
+static int local_pll_clk_enable(struct clk *c)
 {
 	unsigned long flags;
-	struct pll_clk *pll = to_pll_clk(clk);
+	struct pll_clk *pll = to_pll_clk(c);
 
 	spin_lock_irqsave(&pll_reg_lock, flags);
 	__pll_clk_enable_reg(PLL_MODE_REG(pll));
@@ -177,10 +176,10 @@
 	writel_relaxed(mode, mode_reg);
 }
 
-static void local_pll_clk_disable(struct clk *clk)
+static void local_pll_clk_disable(struct clk *c)
 {
 	unsigned long flags;
-	struct pll_clk *pll = to_pll_clk(clk);
+	struct pll_clk *pll = to_pll_clk(c);
 
 	/*
 	 * Disable the PLL output, disable test mode, enable
@@ -191,9 +190,9 @@
 	spin_unlock_irqrestore(&pll_reg_lock, flags);
 }
 
-static enum handoff local_pll_clk_handoff(struct clk *clk)
+static enum handoff local_pll_clk_handoff(struct clk *c)
 {
-	struct pll_clk *pll = to_pll_clk(clk);
+	struct pll_clk *pll = to_pll_clk(c);
 	u32 mode = readl_relaxed(PLL_MODE_REG(pll));
 	u32 mask = PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL;
 
@@ -203,17 +202,16 @@
 	return HANDOFF_DISABLED_CLK;
 }
 
-static struct clk *local_pll_clk_get_parent(struct clk *clk)
+static struct clk *local_pll_clk_get_parent(struct clk *c)
 {
-	struct pll_clk *pll = to_pll_clk(clk);
-	return pll->parent;
+	return to_pll_clk(c)->parent;
 }
 
-int sr_pll_clk_enable(struct clk *clk)
+int sr_pll_clk_enable(struct clk *c)
 {
 	u32 mode;
 	unsigned long flags;
-	struct pll_clk *pll = to_pll_clk(clk);
+	struct pll_clk *pll = to_pll_clk(c);
 
 	spin_lock_irqsave(&pll_reg_lock, flags);
 	mode = readl_relaxed(PLL_MODE_REG(pll));
@@ -250,10 +248,10 @@
 
 #define PLL_LOCKED_BIT BIT(16)
 
-int copper_pll_clk_enable(struct clk *clk)
+int copper_pll_clk_enable(struct clk *c)
 {
 	unsigned long flags;
-	struct pll_clk *pll = to_pll_clk(clk);
+	struct pll_clk *pll = to_pll_clk(c);
 	u32 count, mode;
 	int ret = 0;
 
@@ -282,7 +280,7 @@
 	}
 
 	if (!(readl_relaxed(PLL_STATUS_REG(pll)) & PLL_LOCKED_BIT)) {
-		WARN("PLL %s didn't lock after enabling it!\n", clk->dbg_name);
+		WARN("PLL %s didn't lock after enabling it!\n", c->dbg_name);
 		ret = -ETIMEDOUT;
 		goto out;
 	}
@@ -379,9 +377,9 @@
 
 }
 
-static int pll_clk_enable(struct clk *clk)
+static int pll_clk_enable(struct clk *c)
 {
-	struct pll_shared_clk *pll = to_pll_shared_clk(clk);
+	struct pll_shared_clk *pll = to_pll_shared_clk(c);
 	unsigned int pll_id = pll->id;
 
 	remote_spin_lock(&pll_lock);
@@ -396,9 +394,9 @@
 	return 0;
 }
 
-static void pll_clk_disable(struct clk *clk)
+static void pll_clk_disable(struct clk *c)
 {
-	struct pll_shared_clk *pll = to_pll_shared_clk(clk);
+	struct pll_shared_clk *pll = to_pll_shared_clk(c);
 	unsigned int pll_id = pll->id;
 
 	remote_spin_lock(&pll_lock);
@@ -413,16 +411,14 @@
 	remote_spin_unlock(&pll_lock);
 }
 
-static int pll_clk_is_enabled(struct clk *clk)
+static int pll_clk_is_enabled(struct clk *c)
 {
-	struct pll_shared_clk *pll = to_pll_shared_clk(clk);
-
-	return readl_relaxed(PLL_MODE_REG(pll)) & BIT(0);
+	return readl_relaxed(PLL_MODE_REG(to_pll_shared_clk(c))) & BIT(0);
 }
 
-static enum handoff pll_clk_handoff(struct clk *clk)
+static enum handoff pll_clk_handoff(struct clk *c)
 {
-	struct pll_shared_clk *pll = to_pll_shared_clk(clk);
+	struct pll_shared_clk *pll = to_pll_shared_clk(c);
 	unsigned int pll_lval;
 	struct pll_rate *l;
 
@@ -438,12 +434,12 @@
 	/* Convert PLL L values to PLL Output rate */
 	for (l = pll_l_rate; l->rate != 0; l++) {
 		if (l->lvalue == pll_lval) {
-			clk->rate = l->rate;
+			c->rate = l->rate;
 			break;
 		}
 	}
 
-	if (!clk->rate) {
+	if (!c->rate) {
 		pr_crit("Unknown PLL's L value!\n");
 		BUG();
 	}
diff --git a/arch/arm/mach-msm/clock-pll.h b/arch/arm/mach-msm/clock-pll.h
index a8c642f..f24b066 100644
--- a/arch/arm/mach-msm/clock-pll.h
+++ b/arch/arm/mach-msm/clock-pll.h
@@ -34,7 +34,7 @@
  * @id: PLL ID
  * @mode_reg: enable register
  * @parent: clock source
- * @c: clk
+ * @c: clock
  */
 struct pll_shared_clk {
 	unsigned int id;
@@ -45,9 +45,9 @@
 
 extern struct clk_ops clk_ops_pll;
 
-static inline struct pll_shared_clk *to_pll_shared_clk(struct clk *clk)
+static inline struct pll_shared_clk *to_pll_shared_clk(struct clk *c)
 {
-	return container_of(clk, struct pll_shared_clk, c);
+	return container_of(c, struct pll_shared_clk, c);
 }
 
 /**
@@ -64,7 +64,7 @@
  * @status_mask: ANDed with @status_reg to determine if PLL is active.
  * @status_reg: status register
  * @parent: clock source
- * @c: clk
+ * @c: clock
  */
 struct pll_vote_clk {
 	u32 *soft_vote;
@@ -81,9 +81,9 @@
 
 extern struct clk_ops clk_ops_pll_vote;
 
-static inline struct pll_vote_clk *to_pll_vote_clk(struct clk *clk)
+static inline struct pll_vote_clk *to_pll_vote_clk(struct clk *c)
 {
-	return container_of(clk, struct pll_vote_clk, c);
+	return container_of(c, struct pll_vote_clk, c);
 }
 
 /**
@@ -105,21 +105,21 @@
 
 extern struct clk_ops clk_ops_local_pll;
 
-static inline struct pll_clk *to_pll_clk(struct clk *clk)
+static inline struct pll_clk *to_pll_clk(struct clk *c)
 {
-	return container_of(clk, struct pll_clk, c);
+	return container_of(c, struct pll_clk, c);
 }
 
-int sr_pll_clk_enable(struct clk *clk);
-int copper_pll_clk_enable(struct clk *clk);
+int sr_pll_clk_enable(struct clk *c);
+int copper_pll_clk_enable(struct clk *c);
 
 /*
  * PLL vote clock APIs
  */
-int pll_vote_clk_enable(struct clk *clk);
-void pll_vote_clk_disable(struct clk *clk);
-struct clk *pll_vote_clk_get_parent(struct clk *clk);
-int pll_vote_clk_is_enabled(struct clk *clk);
+int pll_vote_clk_enable(struct clk *c);
+void pll_vote_clk_disable(struct clk *c);
+struct clk *pll_vote_clk_get_parent(struct clk *c);
+int pll_vote_clk_is_enabled(struct clk *c);
 
 struct pll_config {
 	u32 l;
diff --git a/arch/arm/mach-msm/clock-rpm.c b/arch/arm/mach-msm/clock-rpm.c
index e35e8d4..8096c10 100644
--- a/arch/arm/mach-msm/clock-rpm.c
+++ b/arch/arm/mach-msm/clock-rpm.c
@@ -51,7 +51,7 @@
 	int rc;
 	struct msm_rpm_iv_pair iv = { .id = r->rpm_status_id, };
 	rc = msm_rpm_get_status(&iv, 1);
-	return (rc < 0) ? rc : iv.value * 1000;
+	return (rc < 0) ? rc : iv.value * r->factor;
 }
 
 #define RPM_SMD_KEY_RATE	0x007A484B
@@ -192,7 +192,7 @@
 	unsigned long this_khz, this_sleep_khz;
 	int rc = 0;
 
-	this_khz = DIV_ROUND_UP(rate, 1000);
+	this_khz = DIV_ROUND_UP(rate, r->factor);
 
 	spin_lock_irqsave(&rpm_clock_lock, flags);
 
@@ -277,7 +277,7 @@
 	if (!r->branch) {
 		r->last_set_khz = iv.value;
 		r->last_set_sleep_khz = iv.value;
-		clk->rate = iv.value * 1000;
+		clk->rate = iv.value * r->factor;
 	}
 
 	return HANDOFF_ENABLED_CLK;
diff --git a/arch/arm/mach-msm/clock-rpm.h b/arch/arm/mach-msm/clock-rpm.h
index b2358bc..107fb02 100644
--- a/arch/arm/mach-msm/clock-rpm.h
+++ b/arch/arm/mach-msm/clock-rpm.h
@@ -32,6 +32,7 @@
 	unsigned last_set_sleep_khz;
 	bool enabled;
 	bool branch; /* true: RPM only accepts 1 for ON and 0 for OFF */
+	unsigned factor;
 	struct clk_rpmrs_data *rpmrs_data;
 
 	struct rpm_clk *peer;
@@ -53,6 +54,7 @@
 		.rpm_clk_id = (r_id), \
 		.rpm_status_id = (stat_id), \
 		.peer = &active, \
+		.factor = 1000, \
 		.rpmrs_data = (rpmrsdata),\
 		.c = { \
 			.ops = &clk_ops_rpm, \
@@ -68,6 +70,7 @@
 		.rpm_status_id = (stat_id), \
 		.peer = &name, \
 		.active_only = true, \
+		.factor = 1000, \
 		.rpmrs_data = (rpmrsdata),\
 		.c = { \
 			.ops = &clk_ops_rpm, \
@@ -88,6 +91,7 @@
 		.peer = &active, \
 		.last_set_khz = ((r) / 1000), \
 		.last_set_sleep_khz = ((r) / 1000), \
+		.factor = 1000, \
 		.branch = true, \
 		.rpmrs_data = (rpmrsdata),\
 		.c = { \
@@ -106,6 +110,7 @@
 		.peer = &name, \
 		.last_set_khz = ((r) / 1000), \
 		.active_only = true, \
+		.factor = 1000, \
 		.branch = true, \
 		.rpmrs_data = (rpmrsdata),\
 		.c = { \
@@ -118,10 +123,48 @@
 		}, \
 	};
 
+#define __DEFINE_CLK_RPM_QDSS(name, active, type, r_id, stat_id, rpmrsdata) \
+	static struct rpm_clk active; \
+	static struct rpm_clk name = { \
+		.rpm_res_type = (type), \
+		.rpm_clk_id = (r_id), \
+		.rpm_status_id = (stat_id), \
+		.peer = &active, \
+		.factor = 1, \
+		.rpmrs_data = (rpmrsdata),\
+		.c = { \
+			.ops = &clk_ops_rpm, \
+			.flags = CLKFLAG_SKIP_AUTO_OFF, \
+			.dbg_name = #name, \
+			CLK_INIT(name.c), \
+			.warned = true, \
+		}, \
+	}; \
+	static struct rpm_clk active = { \
+		.rpm_res_type = (type), \
+		.rpm_clk_id = (r_id), \
+		.rpm_status_id = (stat_id), \
+		.peer = &name, \
+		.active_only = true, \
+		.factor = 1, \
+		.rpmrs_data = (rpmrsdata),\
+		.c = { \
+			.ops = &clk_ops_rpm, \
+			.flags = CLKFLAG_SKIP_AUTO_OFF, \
+			.dbg_name = #active, \
+			CLK_INIT(active.c), \
+			.warned = true, \
+		}, \
+	};
+
 #define DEFINE_CLK_RPM(name, active, r_id, dep) \
 	__DEFINE_CLK_RPM(name, active, 0, MSM_RPM_ID_##r_id##_CLK, \
 		MSM_RPM_STATUS_ID_##r_id##_CLK, dep, &clk_rpmrs_data)
 
+#define DEFINE_CLK_RPM_QDSS(name, active) \
+	__DEFINE_CLK_RPM_QDSS(name, active, 0, MSM_RPM_ID_QDSS_CLK, \
+		MSM_RPM_STATUS_ID_QDSS_CLK, &clk_rpmrs_data)
+
 #define DEFINE_CLK_RPM_BRANCH(name, active, r_id, r) \
 	__DEFINE_CLK_RPM_BRANCH(name, active, 0, MSM_RPM_ID_##r_id##_CLK, \
 			MSM_RPM_STATUS_ID_##r_id##_CLK, r, &clk_rpmrs_data)
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index cc3c6db..472a87e 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -17,6 +17,7 @@
 #include <linux/msm_rotator.h>
 #include <linux/clkdev.h>
 #include <linux/dma-mapping.h>
+#include <linux/coresight.h>
 #include <mach/irqs-8064.h>
 #include <mach/board.h>
 #include <mach/msm_iomap.h>
@@ -32,7 +33,6 @@
 #include <mach/msm_smd.h>
 #include <mach/msm_dcvs.h>
 #include <mach/msm_rtb.h>
-#include <mach/qdss.h>
 #include <linux/ion.h>
 #include "clock.h"
 #include "devices.h"
diff --git a/arch/arm/mach-msm/devices-8930.c b/arch/arm/mach-msm/devices-8930.c
index c480bba..6ea8d7b 100644
--- a/arch/arm/mach-msm/devices-8930.c
+++ b/arch/arm/mach-msm/devices-8930.c
@@ -25,6 +25,7 @@
 #include <mach/socinfo.h>
 #include <mach/iommu_domains.h>
 #include <mach/msm_rtb.h>
+#include <mach/msm_cache_dump.h>
 
 #include "devices.h"
 #include "rpm_log.h"
@@ -901,3 +902,23 @@
 		.platform_data = &msm8930_rtb_pdata,
 	},
 };
+
+#define MSM8930_L1_SIZE  SZ_1M
+/*
+ * The actual L2 size is smaller but we need a larger buffer
+ * size to store other dump information
+ */
+#define MSM8930_L2_SIZE  SZ_4M
+
+struct msm_cache_dump_platform_data msm8930_cache_dump_pdata = {
+	.l2_size = MSM8930_L2_SIZE,
+	.l1_size = MSM8930_L1_SIZE,
+};
+
+struct platform_device msm8930_cache_dump_device = {
+	.name           = "msm_cache_dump",
+	.id             = -1,
+	.dev            = {
+		.platform_data = &msm8930_cache_dump_pdata,
+	},
+};
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 550a283..3522e80 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -17,6 +17,7 @@
 #include <linux/msm_rotator.h>
 #include <linux/ion.h>
 #include <linux/gpio.h>
+#include <linux/coresight.h>
 #include <asm/clkdev.h>
 #include <linux/msm_kgsl.h>
 #include <linux/android_pmem.h>
@@ -37,7 +38,6 @@
 #include <sound/msm-dai-q6.h>
 #include <sound/apr_audio.h>
 #include <mach/msm_tsif.h>
-#include <mach/qdss.h>
 #include <mach/msm_serial_hs_lite.h>
 #include "clock.h"
 #include "devices.h"
diff --git a/arch/arm/mach-msm/devices-fsm9xxx.c b/arch/arm/mach-msm/devices-fsm9xxx.c
index 777b6d6..5f4d940 100644
--- a/arch/arm/mach-msm/devices-fsm9xxx.c
+++ b/arch/arm/mach-msm/devices-fsm9xxx.c
@@ -71,6 +71,26 @@
 	.resource	= resources_uart2,
 };
 
+static struct resource resources_uart3[] = {
+	{
+		.start	= INT_UART3,
+		.end	= INT_UART3,
+		.flags	= IORESOURCE_IRQ,
+	},
+	{
+		.start	= MSM_UART3_PHYS,
+		.end	= MSM_UART3_PHYS + MSM_UART3_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+struct platform_device msm_device_uart3 = {
+	.name	= "msm_uim",
+	.id	= 2,
+	.num_resources	= ARRAY_SIZE(resources_uart3),
+	.resource	= resources_uart3,
+};
+
 /*
  * SSBIs
  */
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 553f52f..1c58490 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -558,8 +558,8 @@
 	},
 	{
 		.name	= "sdcc_dma_chnl",
-		.start	= DMOV_SDC3_CHAN,
-		.end	= DMOV_SDC3_CHAN,
+		.start	= DMOV_NAND_CHAN,
+		.end	= DMOV_NAND_CHAN,
 		.flags	= IORESOURCE_DMA,
 	},
 	{
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
index ff747e2..722575d 100644
--- a/arch/arm/mach-msm/devices-msm7x30.c
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -820,8 +820,8 @@
 	},
 	{
 		.name	= "sdcc_dma_chnl",
-		.start	= DMOV_SDC2_CHAN,
-		.end	= DMOV_SDC2_CHAN,
+		.start	= DMOV_NAND_CHAN,
+		.end	= DMOV_NAND_CHAN,
 		.flags	= IORESOURCE_DMA,
 	},
 	{
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index ea47727..152ca5b 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -406,6 +406,7 @@
 
 extern struct platform_device msm8960_cache_dump_device;
 extern struct platform_device apq8064_cache_dump_device;
+extern struct platform_device msm8930_cache_dump_device;
 
 extern struct platform_device copper_device_tz_log;
 
diff --git a/arch/arm/mach-msm/footswitch-pcom.c b/arch/arm/mach-msm/footswitch-pcom.c
index 07d7118..8903859 100644
--- a/arch/arm/mach-msm/footswitch-pcom.c
+++ b/arch/arm/mach-msm/footswitch-pcom.c
@@ -42,7 +42,6 @@
  * @init_data: Regulator platform data
  * @pcom_id: Proc-comm ID of the footswitch
  * @is_enabled: Flag set when footswitch is enabled
- * @is_manual: Flag set when footswitch is in manual proc-comm mode
  * @has_ahb_clk: Flag set if footswitched core has an ahb_clk
  * @has_src_clk: Flag set if footswitched core has a src_clk
  * @src_clk: Controls the core clock's rate
@@ -57,7 +56,6 @@
 	struct regulator_init_data		init_data;
 	unsigned				pcom_id;
 	bool					is_enabled;
-	bool					is_manual;
 	struct clk				*src_clk;
 	struct clk				*core_clk;
 	struct clk				*ahb_clk;
@@ -256,12 +254,19 @@
 	if (pdev->id >= MAX_FS)
 		return -ENODEV;
 
-	fs = &footswitches[pdev->id];
-	if (!fs->is_manual) {
-		pr_err("%s is not in manual mode\n", fs->desc.name);
-		return -EINVAL;
-	}
 	init_data = pdev->dev.platform_data;
+	fs = &footswitches[pdev->id];
+
+	/*
+	 * Enable footswitch in manual mode (ie. not controlled along
+	 * with pcom clocks).
+	 */
+	rc = set_rail_state(fs->pcom_id, PCOM_CLKCTL_RPC_RAIL_ENABLE);
+	if (rc)
+		return rc;
+	rc = set_rail_mode(fs->pcom_id, PCOM_RAIL_MODE_MANUAL);
+	if (rc)
+		return rc;
 
 	rc = get_clocks(&pdev->dev, fs);
 	if (rc)
@@ -305,21 +310,6 @@
 
 static int __init footswitch_init(void)
 {
-	struct footswitch *fs;
-	int ret;
-
-	/*
-	 * Enable all footswitches in manual mode (ie. not controlled along
-	 * with pcom clocks).
-	 */
-	for (fs = footswitches; fs < footswitches + ARRAY_SIZE(footswitches);
-	     fs++) {
-		set_rail_state(fs->pcom_id, PCOM_CLKCTL_RPC_RAIL_ENABLE);
-		ret = set_rail_mode(fs->pcom_id, PCOM_RAIL_MODE_MANUAL);
-		if (!ret)
-			fs->is_manual = 1;
-	}
-
 	return platform_driver_register(&footswitch_driver);
 }
 subsys_initcall(footswitch_init);
diff --git a/arch/arm/mach-msm/gdsc.c b/arch/arm/mach-msm/gdsc.c
index df3a92d..f91e3dc 100644
--- a/arch/arm/mach-msm/gdsc.c
+++ b/arch/arm/mach-msm/gdsc.c
@@ -63,10 +63,18 @@
 
 	ret = readl_tight_poll_timeout(sc->gdscr, regval, regval & PWR_ON_MASK,
 				       TIMEOUT_US);
-	if (ret)
+	if (ret) {
 		dev_err(&rdev->dev, "%s enable timed out\n", sc->rdesc.name);
+		return ret;
+	}
 
-	return ret;
+	/*
+	 * If clocks to this power domain were already on, they will take an
+	 * additional 4 clock cycles to re-enable after the rail is enabled.
+	 */
+	udelay(1);
+
+	return 0;
 }
 
 static int gdsc_disable(struct regulator_dev *rdev)
diff --git a/arch/arm/mach-msm/gss-8064.c b/arch/arm/mach-msm/gss-8064.c
index 126f8e0..e65f2d2 100644
--- a/arch/arm/mach-msm/gss-8064.c
+++ b/arch/arm/mach-msm/gss-8064.c
@@ -69,40 +69,12 @@
 	wmb();
 }
 
-static void gss_fatal_fn(struct work_struct *work)
+static void restart_gss(void)
 {
-	uint32_t panic_smsm_states = SMSM_RESET | SMSM_SYSTEM_DOWNLOAD;
-	uint32_t reset_smsm_states = SMSM_SYSTEM_REBOOT_USR |
-					SMSM_SYSTEM_PWRDWN_USR;
-	uint32_t gss_state;
-
-	pr_err("Watchdog bite received from GSS!\n");
-
-	gss_state = smsm_get_state(SMSM_MODEM_STATE);
-
-	if (gss_state & panic_smsm_states) {
-
-		pr_err("GSS SMSM state changed to SMSM_RESET.\n"
-			"Probable err_fatal on the GSS. "
-			"Calling subsystem restart...\n");
-		log_gss_sfr();
-		subsystem_restart("gss");
-
-	} else if (gss_state & reset_smsm_states) {
-
-		pr_err("%s: User-invoked system reset/powerdown. "
-			"Resetting the SoC now.\n",
-			__func__);
-		kernel_restart(NULL);
-	} else {
-		/* TODO: Bus unlock code/sequence goes _here_ */
-		log_gss_sfr();
-		subsystem_restart("gss");
-	}
+	log_gss_sfr();
+	subsystem_restart("gss");
 }
 
-static DECLARE_WORK(gss_fatal_work, gss_fatal_fn);
-
 static void smsm_state_cb(void *data, uint32_t old_state, uint32_t new_state)
 {
 	/* Ignore if we're the one that set SMSM_RESET */
@@ -113,8 +85,7 @@
 		pr_err("GSS SMSM state changed to SMSM_RESET.\n"
 			"Probable err_fatal on the GSS. "
 			"Calling subsystem restart...\n");
-		log_gss_sfr();
-		subsystem_restart("gss");
+		restart_gss();
 	}
 }
 
@@ -180,8 +151,8 @@
 
 static irqreturn_t gss_wdog_bite_irq(int irq, void *dev_id)
 {
-	schedule_work(&gss_fatal_work);
-	disable_irq_nosync(GSS_A5_WDOG_EXPIRED);
+	pr_err("Watchdog bite received from GSS!\n");
+	restart_gss();
 
 	return IRQ_HANDLED;
 }
diff --git a/arch/arm/mach-msm/hotplug.c b/arch/arm/mach-msm/hotplug.c
index 46e835f..f8324ce 100644
--- a/arch/arm/mach-msm/hotplug.c
+++ b/arch/arm/mach-msm/hotplug.c
@@ -16,7 +16,7 @@
 #include <asm/smp_plat.h>
 #include <asm/vfp.h>
 
-#include <mach/qdss.h>
+#include <mach/jtag.h>
 #include <mach/msm_rtb.h>
 
 #include "pm.h"
diff --git a/arch/arm/mach-msm/include/mach/jtag.h b/arch/arm/mach-msm/include/mach/jtag.h
new file mode 100644
index 0000000..3850eff
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/jtag.h
@@ -0,0 +1,24 @@
+/* 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.
+ */
+
+#ifndef __MACH_JTAG_H
+#define __MACH_JTAG_H
+
+#ifdef CONFIG_MSM_JTAG
+extern void msm_jtag_save_state(void);
+extern void msm_jtag_restore_state(void);
+#else
+static inline void msm_jtag_save_state(void) {}
+static inline void msm_jtag_restore_state(void) {}
+#endif
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/mdm2.h b/arch/arm/mach-msm/include/mach/mdm2.h
index 09839b2..2bcdf07 100644
--- a/arch/arm/mach-msm/include/mach/mdm2.h
+++ b/arch/arm/mach-msm/include/mach/mdm2.h
@@ -27,6 +27,7 @@
 	int soft_reset_inverted;
 	int early_power_on;
 	int sfr_query;
+	int no_powerdown_after_ramdumps;
 	struct mdm_vddmin_resource *vddmin_resource;
 	struct platform_device *peripheral_platform_device;
 };
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-fsm9xxx.h b/arch/arm/mach-msm/include/mach/msm_iomap-fsm9xxx.h
index c30c9e4..a99f1f7 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-fsm9xxx.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-fsm9xxx.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
@@ -78,7 +78,10 @@
 #define MSM_UART1_PHYS        0x94000000
 #define MSM_UART1_SIZE        SZ_4K
 
-#define MSM_UART2_PHYS        0x94100000
+#define MSM_UART2_PHYS        0x94010000
 #define MSM_UART2_SIZE        SZ_4K
 
+#define MSM_UART3_PHYS        0x94100000
+#define MSM_UART3_SIZE        SZ_4K
+
 #endif
diff --git a/arch/arm/mach-msm/include/mach/msm_spi.h b/arch/arm/mach-msm/include/mach/msm_spi.h
index 51081b6..11d3014 100644
--- a/arch/arm/mach-msm/include/mach/msm_spi.h
+++ b/arch/arm/mach-msm/include/mach/msm_spi.h
@@ -21,4 +21,5 @@
 	int (*dma_config)(void);
 	const char *rsl_id;
 	uint32_t pm_lat;
+	uint32_t infinite_mode;
 };
diff --git a/arch/arm/mach-msm/include/mach/qdss.h b/arch/arm/mach-msm/include/mach/qdss.h
deleted file mode 100644
index 05d8577..0000000
--- a/arch/arm/mach-msm/include/mach/qdss.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* 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.
- */
-
-#ifndef __MACH_QDSS_H
-#define __MACH_QDSS_H
-
-struct qdss_source {
-	struct list_head link;
-	const char *name;
-	uint32_t fport_mask;
-};
-
-struct msm_qdss_platform_data {
-	struct qdss_source *src_table;
-	size_t size;
-	uint8_t afamily;
-};
-
-#ifdef CONFIG_MSM_QDSS
-extern struct qdss_source *qdss_get(const char *name);
-extern void qdss_put(struct qdss_source *src);
-extern int qdss_enable(struct qdss_source *src);
-extern void qdss_disable(struct qdss_source *src);
-extern void qdss_disable_sink(void);
-extern int qdss_clk_enable(void);
-extern void qdss_clk_disable(void);
-#else
-static inline struct qdss_source *qdss_get(const char *name) { return NULL; }
-static inline void qdss_put(struct qdss_source *src) {}
-static inline int qdss_enable(struct qdss_source *src) { return -ENOSYS; }
-static inline void qdss_disable(struct qdss_source *src) {}
-static inline void qdss_disable_sink(void) {}
-static inline int qdss_clk_enable(void) { return -ENOSYS; }
-static inline void qdss_clk_disable(void) {}
-#endif
-
-#ifdef CONFIG_MSM_JTAG
-extern void msm_jtag_save_state(void);
-extern void msm_jtag_restore_state(void);
-#else
-static inline void msm_jtag_save_state(void) {}
-static inline void msm_jtag_restore_state(void) {}
-#endif
-
-#endif
diff --git a/arch/arm/mach-msm/jtag.c b/arch/arm/mach-msm/jtag.c
index 8dae9c6..bf5857c 100644
--- a/arch/arm/mach-msm/jtag.c
+++ b/arch/arm/mach-msm/jtag.c
@@ -19,11 +19,16 @@
 #include <linux/export.h>
 #include <linux/printk.h>
 #include <linux/ratelimit.h>
+#include <linux/coresight.h>
 #include <mach/scm.h>
+#include <mach/jtag.h>
 
-#include "qdss-priv.h"
 #include "cp14.h"
 
+#define BM(lsb, msb)		((BIT(msb) - BIT(lsb)) + BIT(msb))
+#define BMVAL(val, lsb, msb)	((val & BM(lsb, msb)) >> lsb)
+#define BVAL(val, n)		((val & BIT(n)) >> n)
+
 /* no of dbg regs + 1 (for storing the reg count) */
 #define MAX_DBG_REGS		(90)
 #define MAX_DBG_STATE_SIZE	(MAX_DBG_REGS * num_possible_cpus())
diff --git a/arch/arm/mach-msm/mdm2.c b/arch/arm/mach-msm/mdm2.c
index 4791955..f851545 100644
--- a/arch/arm/mach-msm/mdm2.c
+++ b/arch/arm/mach-msm/mdm2.c
@@ -42,9 +42,6 @@
 #include "clock.h"
 #include "mdm_private.h"
 
-#define MDM_MODEM_TIMEOUT	6000
-#define MDM_HOLD_TIME		4000
-#define MDM_MODEM_DELTA		100
 #define MDM_PBLRDY_CNT		20
 
 static int mdm_debug_on;
@@ -80,20 +77,52 @@
 	mutex_unlock(&hsic_status_lock);
 }
 
+static void mdm_toggle_soft_reset(struct mdm_modem_drv *mdm_drv)
+{
+	int soft_reset_direction_assert = 0,
+	    soft_reset_direction_de_assert = 1;
+
+	if (mdm_drv->pdata->soft_reset_inverted) {
+		soft_reset_direction_assert = 1;
+		soft_reset_direction_de_assert = 0;
+	}
+	gpio_direction_output(mdm_drv->ap2mdm_soft_reset_gpio,
+			soft_reset_direction_assert);
+	usleep_range(5000, 10000);
+	gpio_direction_output(mdm_drv->ap2mdm_soft_reset_gpio,
+			soft_reset_direction_de_assert);
+}
+
 static void mdm_power_down_common(struct mdm_modem_drv *mdm_drv)
 {
+	int i;
 	int soft_reset_direction =
 		mdm_drv->pdata->soft_reset_inverted ? 1 : 0;
 
-	gpio_direction_output(mdm_drv->ap2mdm_soft_reset_gpio,
-				soft_reset_direction);
+	/* Wait for the modem to complete its power down actions. */
+	for (i = 20; i > 0; i--) {
+		if (gpio_get_value(mdm_drv->mdm2ap_status_gpio) == 0)
+			break;
+		msleep(100);
+	}
+	if (i == 0) {
+		pr_err("%s: MDM2AP_STATUS never went low. Doing a hard reset\n",
+			   __func__);
+		gpio_direction_output(mdm_drv->ap2mdm_soft_reset_gpio,
+					soft_reset_direction);
+		/*
+		* Currently, there is a debounce timer on the charm PMIC. It is
+		* necessary to hold the PMIC RESET low for ~3.5 seconds
+		* for the reset to fully take place. Sleep here to ensure the
+		* reset has occured before the function exits.
+		*/
+		msleep(4000);
+	}
 	mdm_peripheral_disconnect(mdm_drv);
 }
 
 static void mdm_do_first_power_on(struct mdm_modem_drv *mdm_drv)
 {
-	int soft_reset_direction =
-		mdm_drv->pdata->soft_reset_inverted ? 0 : 1;
 	int i;
 	int pblrdy;
 
@@ -106,6 +135,13 @@
 	pr_err("%s: Powering on modem for the first time\n", __func__);
 	mdm_peripheral_disconnect(mdm_drv);
 
+	/* If this is the first power-up after a panic, the modem may still
+	 * be in a power-on state, in which case we need to toggle the gpio
+	 * instead of just de-asserting it. No harm done if the modem was
+	 * powered down.
+	 */
+	mdm_toggle_soft_reset(mdm_drv);
+
 	/* If the device has a kpd pwr gpio then toggle it. */
 	if (mdm_drv->ap2mdm_kpdpwr_n_gpio > 0) {
 		/* Pull AP2MDM_KPDPWR gpio high and wait for PS_HOLD to settle,
@@ -117,10 +153,6 @@
 		gpio_direction_output(mdm_drv->ap2mdm_kpdpwr_n_gpio, 0);
 	}
 
-	/* De-assert the soft reset line. */
-	pr_debug("%s: De-asserting soft reset gpio\n", __func__);
-	gpio_direction_output(mdm_drv->ap2mdm_soft_reset_gpio,
-						  soft_reset_direction);
 	if (!mdm_drv->mdm2ap_pblrdy)
 		goto start_mdm_peripheral;
 
@@ -140,21 +172,12 @@
 
 static void mdm_do_soft_power_on(struct mdm_modem_drv *mdm_drv)
 {
-	int soft_reset_direction =
-		mdm_drv->pdata->soft_reset_inverted ? 0 : 1;
 	int i;
 	int pblrdy;
 
-	/* De-assert the soft reset line. */
 	pr_err("%s: soft resetting mdm modem\n", __func__);
-
 	mdm_peripheral_disconnect(mdm_drv);
-
-	gpio_direction_output(mdm_drv->ap2mdm_soft_reset_gpio,
-		soft_reset_direction == 1 ? 0 : 1);
-	usleep_range(5000, 10000);
-	gpio_direction_output(mdm_drv->ap2mdm_soft_reset_gpio,
-		soft_reset_direction == 1 ? 1 : 0);
+	mdm_toggle_soft_reset(mdm_drv);
 
 	if (!mdm_drv->mdm2ap_pblrdy)
 		goto start_mdm_peripheral;
diff --git a/arch/arm/mach-msm/mdm_common.c b/arch/arm/mach-msm/mdm_common.c
index c961731..04ce49f 100644
--- a/arch/arm/mach-msm/mdm_common.c
+++ b/arch/arm/mach-msm/mdm_common.c
@@ -45,7 +45,7 @@
 #define MDM_MODEM_TIMEOUT	6000
 #define MDM_MODEM_DELTA	100
 #define MDM_BOOT_TIMEOUT	60000L
-#define MDM_RDUMP_TIMEOUT	60000L
+#define MDM_RDUMP_TIMEOUT	120000L
 #define MDM2AP_STATUS_TIMEOUT_MS 60000L
 
 static int mdm_debug_on;
@@ -403,7 +403,8 @@
 			pr_info("%s: mdm modem ramdumps completed.\n",
 					__func__);
 		INIT_COMPLETION(mdm_ram_dumps);
-		mdm_drv->ops->power_down_mdm_cb(mdm_drv);
+		if (!mdm_drv->pdata->no_powerdown_after_ramdumps)
+			mdm_drv->ops->power_down_mdm_cb(mdm_drv);
 	}
 	return mdm_drv->mdm_ram_dump_status;
 }
diff --git a/arch/arm/mach-msm/memory.c b/arch/arm/mach-msm/memory.c
index 40845d7..a1b21c5 100644
--- a/arch/arm/mach-msm/memory.c
+++ b/arch/arm/mach-msm/memory.c
@@ -363,64 +363,6 @@
 }
 EXPORT_SYMBOL(allocate_contiguous_ebi_nomap);
 
-/* emulation of the deprecated pmem_kalloc and pmem_kfree */
-int32_t pmem_kalloc(const size_t size, const uint32_t flags)
-{
-	int pmem_memtype;
-	int memtype = MEMTYPE_NONE;
-	int ebi1_memtype = MEMTYPE_EBI1;
-	unsigned int align;
-	int32_t paddr;
-
-	switch (flags & PMEM_ALIGNMENT_MASK) {
-	case PMEM_ALIGNMENT_4K:
-		align = SZ_4K;
-		break;
-	case PMEM_ALIGNMENT_1M:
-		align = SZ_1M;
-		break;
-	default:
-		pr_alert("Invalid alignment %x\n",
-			(flags & PMEM_ALIGNMENT_MASK));
-		return -EINVAL;
-	}
-
-	/* on 7x30 and 8x55 "EBI1 kernel PMEM" is really on EBI0 */
-	if (cpu_is_msm7x30() || cpu_is_msm8x55())
-			ebi1_memtype = MEMTYPE_EBI0;
-
-	pmem_memtype = flags & PMEM_MEMTYPE_MASK;
-	if (pmem_memtype == PMEM_MEMTYPE_EBI1)
-		memtype = ebi1_memtype;
-	else if (pmem_memtype == PMEM_MEMTYPE_SMI)
-		memtype = MEMTYPE_SMI_KERNEL;
-	else {
-		pr_alert("Invalid memory type %x\n",
-			flags & PMEM_MEMTYPE_MASK);
-		return -EINVAL;
-	}
-
-	paddr = _allocate_contiguous_memory_nomap(size, memtype, align,
-		__builtin_return_address(0));
-
-	if (!paddr && pmem_memtype == PMEM_MEMTYPE_SMI)
-		paddr = _allocate_contiguous_memory_nomap(size,
-			ebi1_memtype, align, __builtin_return_address(0));
-
-	if (!paddr)
-		return -ENOMEM;
-	return paddr;
-}
-EXPORT_SYMBOL(pmem_kalloc);
-
-int pmem_kfree(const int32_t physaddr)
-{
-	free_contiguous_memory_by_paddr(physaddr);
-
-	return 0;
-}
-EXPORT_SYMBOL(pmem_kfree);
-
 unsigned int msm_ttbr0;
 
 void store_ttbr0(void)
diff --git a/arch/arm/mach-msm/perf_event_msm_krait_l2.c b/arch/arm/mach-msm/perf_event_msm_krait_l2.c
index d82f4dd..5f76a92 100644
--- a/arch/arm/mach-msm/perf_event_msm_krait_l2.c
+++ b/arch/arm/mach-msm/perf_event_msm_krait_l2.c
@@ -14,12 +14,17 @@
 #include <linux/irq.h>
 #include <asm/pmu.h>
 #include <linux/platform_device.h>
+#include <linux/spinlock.h>
 
 #include <mach/msm-krait-l2-accessors.h>
 
 #define MAX_L2_PERIOD	((1ULL << 32) - 1)
 #define MAX_KRAIT_L2_CTRS 5
 
+#define L2_EVT_MASK 0xfffff
+
+#define L2_SLAVE_EV_PREFIX 4
+
 #define L2PMCCNTR 0x409
 #define L2PMCCNTCR 0x408
 #define L2PMCCNTSR 0x40A
@@ -48,16 +53,62 @@
 
 /* event format is -e rsRCCG See get_event_desc() */
 
-#define EVENT_REG_MASK		0xf000
-#define EVENT_GROUPSEL_MASK	0x000f
-#define	EVENT_GROUPCODE_MASK	0x0ff0
+#define EVENT_PREFIX_MASK	0xf0000
+#define EVENT_REG_MASK		0x0f000
+#define EVENT_GROUPSEL_MASK	0x0000f
+#define	EVENT_GROUPCODE_MASK	0x00ff0
+
+#define EVENT_PREFIX_SHIFT	16
 #define EVENT_REG_SHIFT		12
 #define EVENT_GROUPCODE_SHIFT	4
 
 #define	RESRX_VALUE_EN	0x80000000
 
+/*
+ * The L2 PMU is shared between all CPU's, so protect
+ * its bitmap access.
+ */
+struct pmu_constraints {
+	u64 pmu_bitmap;
+	raw_spinlock_t lock;
+} l2_pmu_constraints = {
+	.pmu_bitmap = 0,
+	.lock = __RAW_SPIN_LOCK_UNLOCKED(l2_pmu_constraints.lock),
+};
+
+/* NRCCG format for perf RAW codes. */
+PMU_FORMAT_ATTR(l2_prefix, "config:16-19");
+PMU_FORMAT_ATTR(l2_reg,	"config:12-15");
+PMU_FORMAT_ATTR(l2_code, "config:4-11");
+PMU_FORMAT_ATTR(l2_grp,	"config:0-3");
+
+static struct attribute *msm_l2_ev_formats[] = {
+	&format_attr_l2_prefix.attr,
+	&format_attr_l2_reg.attr,
+	&format_attr_l2_code.attr,
+	&format_attr_l2_grp.attr,
+	NULL,
+};
+
+/*
+ * Format group is essential to access PMU's from userspace
+ * via their .name field.
+ */
+static struct attribute_group msm_l2_pmu_format_group = {
+	.name = "format",
+	.attrs = msm_l2_ev_formats,
+};
+
+static const struct attribute_group *msm_l2_pmu_attr_grps[] = {
+	&msm_l2_pmu_format_group,
+	NULL,
+};
+
 static u32 l2_orig_filter_prefix = 0x000f0030;
 
+/* L2 slave port traffic filtering */
+static u32 l2_slv_filter_prefix = 0x000f0010;
+
 static u32 pmu_type;
 
 static struct arm_pmu krait_l2_pmu;
@@ -128,19 +179,25 @@
 	set_l2_indirect_reg(group_reg, resr_val);
 }
 
-static void set_evfilter_task_mode(int ctr)
+static void set_evfilter_task_mode(int ctr, unsigned int is_slv)
 {
 	u32 filter_reg = (ctr * 16) + IA_L2PMXEVFILTER_BASE;
 	u32 filter_val = l2_orig_filter_prefix | 1 << smp_processor_id();
 
+	if (is_slv)
+		filter_val = l2_slv_filter_prefix;
+
 	set_l2_indirect_reg(filter_reg, filter_val);
 }
 
-static void set_evfilter_sys_mode(int ctr)
+static void set_evfilter_sys_mode(int ctr, unsigned int is_slv)
 {
 	u32 filter_reg = (ctr * 16) + IA_L2PMXEVFILTER_BASE;
 	u32 filter_val = l2_orig_filter_prefix | 0xf;
 
+	if (is_slv)
+		filter_val = l2_slv_filter_prefix;
+
 	set_l2_indirect_reg(filter_reg, filter_val);
 }
 
@@ -212,12 +269,21 @@
 {
 	struct event_desc evdesc;
 	unsigned long iflags;
+	unsigned int is_slv = 0;
+	unsigned int evt_prefix;
 
 	raw_spin_lock_irqsave(&krait_l2_pmu_hw_events.pmu_lock, iflags);
 
 	if (hwc->config_base == L2CYCLE_CTR_RAW_CODE)
 		goto out;
 
+	/* Check if user requested any special origin filtering. */
+	evt_prefix = (hwc->config_base &
+			EVENT_PREFIX_MASK) >> EVENT_PREFIX_SHIFT;
+
+	if (evt_prefix == L2_SLAVE_EV_PREFIX)
+		is_slv = 1;
+
 	set_evcntcr(idx);
 
 	memset(&evdesc, 0, sizeof(evdesc));
@@ -230,9 +296,9 @@
 		  evdesc.event_group_code);
 
 	if (cpu < 0)
-		set_evfilter_task_mode(idx);
+		set_evfilter_task_mode(idx, is_slv);
 	else
-		set_evfilter_sys_mode(idx);
+		set_evfilter_sys_mode(idx, is_slv);
 
 out:
 	enable_intenset(idx);
@@ -358,7 +424,7 @@
 static int krait_l2_map_event(struct perf_event *event)
 {
 	if (pmu_type > 0 && pmu_type == event->attr.type)
-		return event->attr.config & 0xfffff;
+		return event->attr.config & L2_EVT_MASK;
 	else
 		return -ENOENT;
 }
@@ -378,6 +444,50 @@
 		free_irq(irq, NULL);
 }
 
+static int msm_l2_test_set_ev_constraint(struct perf_event *event)
+{
+	u32 evt_type = event->attr.config & L2_EVT_MASK;
+	u8 reg   = (evt_type & 0x0F000) >> 12;
+	u8 group =  evt_type & 0x0000F;
+	unsigned long flags;
+	u32 err = 0;
+	u64 bitmap_t;
+
+	raw_spin_lock_irqsave(&l2_pmu_constraints.lock, flags);
+
+	bitmap_t = 1 << ((reg * 4) + group);
+
+	if (!(l2_pmu_constraints.pmu_bitmap & bitmap_t)) {
+		l2_pmu_constraints.pmu_bitmap |= bitmap_t;
+		goto out;
+	}
+
+	/* Bit is already set. Constraint failed. */
+	err = -EPERM;
+out:
+	raw_spin_unlock_irqrestore(&l2_pmu_constraints.lock, flags);
+	return err;
+}
+
+static int msm_l2_clear_ev_constraint(struct perf_event *event)
+{
+	u32 evt_type = event->attr.config & L2_EVT_MASK;
+	u8 reg   = (evt_type & 0x0F000) >> 12;
+	u8 group =  evt_type & 0x0000F;
+	unsigned long flags;
+	u64 bitmap_t;
+
+	raw_spin_lock_irqsave(&l2_pmu_constraints.lock, flags);
+
+	bitmap_t = 1 << ((reg * 4) + group);
+
+	/* Clear constraint bit. */
+	l2_pmu_constraints.pmu_bitmap &= ~bitmap_t;
+
+	raw_spin_unlock_irqrestore(&l2_pmu_constraints.lock, flags);
+	return 1;
+}
+
 static struct arm_pmu krait_l2_pmu = {
 	.id		=	ARM_PERF_PMU_ID_KRAIT_L2,
 	.type		=	ARM_PMU_DEVICE_L2CC,
@@ -393,16 +503,19 @@
 	.read_counter	=	krait_l2_read_counter,
 	.write_counter	=	krait_l2_write_counter,
 	.map_event	=	krait_l2_map_event,
-	.max_period	=	(1LLU << 32) - 1,
+	.max_period	=	MAX_L2_PERIOD,
 	.get_hw_events	=	krait_l2_get_hw_events,
 	.num_events	=	MAX_KRAIT_L2_CTRS,
+	.test_set_event_constraints	= msm_l2_test_set_ev_constraint,
+	.clear_event_constraints	= msm_l2_clear_ev_constraint,
+	.pmu.attr_groups		= msm_l2_pmu_attr_grps,
 };
 
 static int __devinit krait_l2_pmu_device_probe(struct platform_device *pdev)
 {
 	krait_l2_pmu.plat_device = pdev;
 
-	if (!armpmu_register(&krait_l2_pmu, "krait-l2", -1))
+	if (!armpmu_register(&krait_l2_pmu, "kraitl2", -1))
 		pmu_type = krait_l2_pmu.pmu.type;
 
 	return 0;
diff --git a/arch/arm/mach-msm/perf_event_msm_l2.c b/arch/arm/mach-msm/perf_event_msm_l2.c
index 3310d92..5a5bf57 100644
--- a/arch/arm/mach-msm/perf_event_msm_l2.c
+++ b/arch/arm/mach-msm/perf_event_msm_l2.c
@@ -13,6 +13,7 @@
 #include <linux/irq.h>
 #include <asm/pmu.h>
 #include <linux/platform_device.h>
+#include <linux/spinlock.h>
 
 
 #define MAX_SCORPION_L2_CTRS 5
@@ -23,10 +24,61 @@
 #define SCORPION_L2_EVT_PREFIX 3
 #define SCORPION_MAX_L2_REG 4
 
+#define L2_EVT_MASK 0xfffff
+#define L2_EVT_PREFIX_MASK 0xf0000
+#define L2_EVT_PREFIX_SHIFT 16
+#define L2_SLAVE_EVT_PREFIX 4
+
+
+/*
+ * The L2 PMU is shared between all CPU's, so protect
+ * its bitmap access.
+ */
+struct pmu_constraints {
+	u64 pmu_bitmap;
+	raw_spinlock_t lock;
+} l2_pmu_constraints = {
+	.pmu_bitmap = 0,
+	.lock = __RAW_SPIN_LOCK_UNLOCKED(l2_pmu_constraints.lock),
+};
+
+/* NRCCG format for perf RAW codes. */
+PMU_FORMAT_ATTR(l2_prefix,	"config:16-19");
+PMU_FORMAT_ATTR(l2_reg,		"config:12-15");
+PMU_FORMAT_ATTR(l2_code,	"config:4-11");
+PMU_FORMAT_ATTR(l2_grp,		"config:0-3");
+
+static struct attribute *msm_l2_ev_formats[] = {
+	&format_attr_l2_prefix.attr,
+	&format_attr_l2_reg.attr,
+	&format_attr_l2_code.attr,
+	&format_attr_l2_grp.attr,
+	NULL,
+};
+
+/*
+ * Format group is essential to access PMU's from userspace
+ * via their .name field.
+ */
+static struct attribute_group msm_l2_pmu_format_group = {
+	.name = "format",
+	.attrs = msm_l2_ev_formats,
+};
+
+static const struct attribute_group *msm_l2_pmu_attr_grps[] = {
+	&msm_l2_pmu_format_group,
+	NULL,
+};
+
 static u32 pmu_type;
 
 static struct arm_pmu scorpion_l2_pmu;
 
+static u32 l2_orig_filter_prefix = 0x000f0030;
+
+/* L2 slave port traffic filtering */
+static u32 l2_slv_filter_prefix = 0x000f0010;
+
 static struct perf_event *l2_events[MAX_SCORPION_L2_CTRS];
 static unsigned long l2_used_mask[BITS_TO_LONGS(MAX_SCORPION_L2_CTRS)];
 
@@ -376,7 +428,8 @@
 	u8 group;
 
 	prefix = (evt_type & 0xF0000) >> 16;
-	if (prefix == SCORPION_L2_EVT_PREFIX) {
+	if (prefix == SCORPION_L2_EVT_PREFIX ||
+			prefix == L2_SLAVE_EVT_PREFIX) {
 		reg   = (evt_type & 0x0F000) >> 12;
 		code  = (evt_type & 0x00FF0) >> 4;
 		group =  evt_type & 0x0000F;
@@ -433,16 +486,22 @@
 	asm volatile ("mcr p15, 3, %0, c15, c6, 7" : : "r" (val));
 }
 
-static void scorpion_l2_set_evfilter_task_mode(void)
+static void scorpion_l2_set_evfilter_task_mode(unsigned int is_slv)
 {
-	u32 filter_val = 0x000f0030 | 1 << smp_processor_id();
+	u32 filter_val = l2_orig_filter_prefix | 1 << smp_processor_id();
+
+	if (is_slv)
+		filter_val = l2_slv_filter_prefix;
 
 	asm volatile ("mcr p15, 3, %0, c15, c6, 3" : : "r" (filter_val));
 }
 
-static void scorpion_l2_set_evfilter_sys_mode(void)
+static void scorpion_l2_set_evfilter_sys_mode(unsigned int is_slv)
 {
-	u32 filter_val = 0x000f003f;
+	u32 filter_val = l2_orig_filter_prefix | 0xf;
+
+	if (is_slv)
+		filter_val = l2_slv_filter_prefix;
 
 	asm volatile ("mcr p15, 3, %0, c15, c6, 3" : : "r" (filter_val));
 }
@@ -542,12 +601,21 @@
 	int evtype = hwc->config_base;
 	int ev_typer;
 	unsigned long iflags;
+	unsigned int is_slv = 0;
+	unsigned int evt_prefix;
 
 	raw_spin_lock_irqsave(&scorpion_l2_pmu_hw_events.pmu_lock, iflags);
 
 	if (hwc->config_base == SCORPION_L2CYCLE_CTR_RAW_CODE)
 		goto out;
 
+	/* Check if user requested any special origin filtering. */
+	evt_prefix = (hwc->config_base &
+			L2_EVT_PREFIX_MASK) >> L2_EVT_PREFIX_SHIFT;
+
+	if (evt_prefix == L2_SLAVE_EVT_PREFIX)
+		is_slv = 1;
+
 	memset(&evtinfo, 0, sizeof(evtinfo));
 
 	ev_typer = get_scorpion_l2_evtinfo(evtype, &evtinfo);
@@ -557,9 +625,9 @@
 	scorpion_l2_set_evcntcr();
 
 	if (cpu < 0)
-		scorpion_l2_set_evfilter_task_mode();
+		scorpion_l2_set_evfilter_task_mode(is_slv);
 	else
-		scorpion_l2_set_evfilter_sys_mode();
+		scorpion_l2_set_evfilter_sys_mode(is_slv);
 
 	scorpion_l2_evt_setup(evtinfo.grp, evtinfo.val);
 
@@ -693,7 +761,7 @@
 static int scorpion_l2_map_event(struct perf_event *event)
 {
 	if (pmu_type > 0 && pmu_type == event->attr.type)
-		return event->attr.config & 0xfffff;
+		return event->attr.config & L2_EVT_MASK;
 	else
 		return -ENOENT;
 }
@@ -713,6 +781,59 @@
 		free_irq(irq, NULL);
 }
 
+static int msm_l2_test_set_ev_constraint(struct perf_event *event)
+{
+	u32 evt_type = event->attr.config & L2_EVT_MASK;
+	u8 prefix = (evt_type & 0xF0000) >> 16;
+	u8 reg   = (evt_type & 0x0F000) >> 12;
+	u8 group =  evt_type & 0x0000F;
+	unsigned long flags;
+	u32 err = 0;
+	u64 bitmap_t;
+
+	if (!prefix)
+		return 0;
+
+	raw_spin_lock_irqsave(&l2_pmu_constraints.lock, flags);
+
+	bitmap_t = 1 << ((reg * 4) + group);
+
+	if (!(l2_pmu_constraints.pmu_bitmap & bitmap_t)) {
+		l2_pmu_constraints.pmu_bitmap |= bitmap_t;
+		goto out;
+	}
+
+	/* Bit is already set. Constraint failed. */
+	err = -EPERM;
+
+out:
+	raw_spin_unlock_irqrestore(&l2_pmu_constraints.lock, flags);
+	return err;
+}
+
+static int msm_l2_clear_ev_constraint(struct perf_event *event)
+{
+	u32 evt_type = event->attr.config & L2_EVT_MASK;
+	u8 prefix = (evt_type & 0xF0000) >> 16;
+	u8 reg   = (evt_type & 0x0F000) >> 12;
+	u8 group =  evt_type & 0x0000F;
+	unsigned long flags;
+	u64 bitmap_t;
+
+	if (!prefix)
+		return 0;
+
+	raw_spin_lock_irqsave(&l2_pmu_constraints.lock, flags);
+
+	bitmap_t = 1 << ((reg * 4) + group);
+
+	/* Clear constraint bit. */
+	l2_pmu_constraints.pmu_bitmap &= ~bitmap_t;
+
+	raw_spin_unlock_irqrestore(&l2_pmu_constraints.lock, flags);
+	return 1;
+}
+
 static struct arm_pmu scorpion_l2_pmu = {
 	.id		=	ARM_PERF_PMU_ID_SCORPIONMP_L2,
 	.type		=	ARM_PMU_DEVICE_L2CC,
@@ -731,13 +852,16 @@
 	.max_period	=	(1LLU << 32) - 1,
 	.get_hw_events	=	scorpion_l2_get_hw_events,
 	.num_events	=	MAX_SCORPION_L2_CTRS,
+	.test_set_event_constraints	= msm_l2_test_set_ev_constraint,
+	.clear_event_constraints	= msm_l2_clear_ev_constraint,
+	.pmu.attr_groups		= msm_l2_pmu_attr_grps,
 };
 
 static int __devinit scorpion_l2_pmu_device_probe(struct platform_device *pdev)
 {
 	scorpion_l2_pmu.plat_device = pdev;
 
-	if (!armpmu_register(&scorpion_l2_pmu, "scorpion-l2", -1))
+	if (!armpmu_register(&scorpion_l2_pmu, "scorpionl2", -1))
 		pmu_type = scorpion_l2_pmu.pmu.type;
 
 	return 0;
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_lpa.c b/arch/arm/mach-msm/qdsp5v2/audio_lpa.c
index d5fb2e9..60f43b9 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_lpa.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_lpa.c
@@ -34,6 +34,7 @@
 #include <linux/slab.h>
 #include <linux/msm_audio.h>
 #include <mach/qdsp5v2/audio_dev_ctl.h>
+#include <linux/memory_alloc.h>
 
 #include <mach/qdsp5v2/qdsp5audppmsg.h>
 #include <mach/qdsp5v2/qdsp5audplaycmdi.h>
@@ -1410,7 +1411,7 @@
 	wake_up(&audio->event_wait);
 	audlpa_reset_event_queue(audio);
 	iounmap(audio->data);
-	pmem_kfree(audio->phys);
+	free_contiguous_memory_by_paddr(audio->phys);
 	mutex_unlock(&audio->lock);
 #ifdef CONFIG_DEBUG_FS
 	if (audio->dentry)
@@ -1655,7 +1656,7 @@
 	msm_adsp_put(audio->audplay);
 err:
 	iounmap(audio->data);
-	pmem_kfree(audio->phys);
+	free_contiguous_memory_by_paddr(audio->phys);
 	audpp_adec_free(audio->dec_id);
 	MM_INFO("audio instance 0x%08x freeing\n", (int)audio);
 	kfree(audio);
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_mvs.c b/arch/arm/mach-msm/qdsp5v2/audio_mvs.c
index 99da836..1884b3c 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_mvs.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_mvs.c
@@ -304,6 +304,7 @@
 	uint32_t buf_free_cnt;
 	uint32_t rate_type;
 	uint32_t dtx_mode;
+	struct min_max_rate min_max_rate;
 
 	struct msm_rpc_endpoint *rpc_endpt;
 	uint32_t rpc_prog;
@@ -416,8 +417,10 @@
 
 		/* Set EVRC mode. */
 		memset(&set_voc_mode_msg, 0, sizeof(set_voc_mode_msg));
-		set_voc_mode_msg.min_rate = cpu_to_be32(audio->rate_type);
-		set_voc_mode_msg.max_rate = cpu_to_be32(audio->rate_type);
+		set_voc_mode_msg.min_rate =
+				cpu_to_be32(audio->min_max_rate.min_rate);
+		set_voc_mode_msg.max_rate =
+				cpu_to_be32(audio->min_max_rate.max_rate);
 
 		msm_rpc_setup_req(&set_voc_mode_msg.rpc_hdr,
 				  audio->rpc_prog,
@@ -1555,6 +1558,8 @@
 		mutex_lock(&audio->lock);
 		config.mvs_mode = audio->mvs_mode;
 		config.rate_type = audio->rate_type;
+		config.min_max_rate.min_rate = audio->min_max_rate.min_rate;
+		config.min_max_rate.max_rate = audio->min_max_rate.max_rate;
 		mutex_unlock(&audio->lock);
 
 		rc = copy_to_user((void *)arg, &config, sizeof(config));
@@ -1579,6 +1584,10 @@
 				audio->mvs_mode = config.mvs_mode;
 				audio->rate_type = config.rate_type;
 				audio->dtx_mode = config.dtx_mode;
+				audio->min_max_rate.min_rate =
+						config.min_max_rate.min_rate;
+				audio->min_max_rate.max_rate =
+						config.min_max_rate.max_rate;
 			} else {
 				pr_err("%s: Set confg called in state %d\n",
 				       __func__, audio->state);
diff --git a/arch/arm/mach-msm/qdss-etb.c b/arch/arm/mach-msm/qdss-etb.c
deleted file mode 100644
index ccea2fa..0000000
--- a/arch/arm/mach-msm/qdss-etb.c
+++ /dev/null
@@ -1,419 +0,0 @@
-/* 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
- * 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/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/err.h>
-#include <linux/fs.h>
-#include <linux/miscdevice.h>
-#include <linux/uaccess.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-
-#include "qdss-priv.h"
-
-#define etb_writel(etb, val, off)	__raw_writel((val), etb.base + off)
-#define etb_readl(etb, off)		__raw_readl(etb.base + off)
-
-#define ETB_RAM_DEPTH_REG	(0x004)
-#define ETB_STATUS_REG		(0x00C)
-#define ETB_RAM_READ_DATA_REG	(0x010)
-#define ETB_RAM_READ_POINTER	(0x014)
-#define ETB_RAM_WRITE_POINTER	(0x018)
-#define ETB_TRG			(0x01C)
-#define ETB_CTL_REG		(0x020)
-#define ETB_RWD_REG		(0x024)
-#define ETB_FFSR		(0x300)
-#define ETB_FFCR		(0x304)
-#define ETB_ITMISCOP0		(0xEE0)
-#define ETB_ITTRFLINACK		(0xEE4)
-#define ETB_ITTRFLIN		(0xEE8)
-#define ETB_ITATBDATA0		(0xEEC)
-#define ETB_ITATBCTR2		(0xEF0)
-#define ETB_ITATBCTR1		(0xEF4)
-#define ETB_ITATBCTR0		(0xEF8)
-
-
-#define BYTES_PER_WORD		4
-#define ETB_SIZE_WORDS		4096
-#define FRAME_SIZE_WORDS	4
-
-#define ETB_LOCK()							\
-do {									\
-	mb();								\
-	etb_writel(etb, 0x0, CS_LAR);					\
-} while (0)
-#define ETB_UNLOCK()							\
-do {									\
-	etb_writel(etb, CS_UNLOCK_MAGIC, CS_LAR);			\
-	mb();								\
-} while (0)
-
-struct etb_ctx {
-	uint8_t		*buf;
-	void __iomem	*base;
-	bool		enabled;
-	bool		reading;
-	spinlock_t	spinlock;
-	atomic_t	in_use;
-	struct device	*dev;
-	struct kobject	*kobj;
-	uint32_t	trigger_cntr;
-};
-
-static struct etb_ctx etb;
-
-static void __etb_enable(void)
-{
-	int i;
-
-	ETB_UNLOCK();
-
-	etb_writel(etb, 0x0, ETB_RAM_WRITE_POINTER);
-	for (i = 0; i < ETB_SIZE_WORDS; i++)
-		etb_writel(etb, 0x0, ETB_RWD_REG);
-
-	etb_writel(etb, 0x0, ETB_RAM_WRITE_POINTER);
-	etb_writel(etb, 0x0, ETB_RAM_READ_POINTER);
-
-	etb_writel(etb, etb.trigger_cntr, ETB_TRG);
-	etb_writel(etb, BIT(13) | BIT(0), ETB_FFCR);
-	etb_writel(etb, BIT(0), ETB_CTL_REG);
-
-	ETB_LOCK();
-}
-
-void etb_enable(void)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&etb.spinlock, flags);
-	__etb_enable();
-	etb.enabled = true;
-	dev_info(etb.dev, "ETB enabled\n");
-	spin_unlock_irqrestore(&etb.spinlock, flags);
-}
-
-static void __etb_disable(void)
-{
-	int count;
-	uint32_t ffcr;
-
-	ETB_UNLOCK();
-
-	ffcr = etb_readl(etb, ETB_FFCR);
-	ffcr |= (BIT(12) | BIT(6));
-	etb_writel(etb, ffcr, ETB_FFCR);
-
-	for (count = TIMEOUT_US; BVAL(etb_readl(etb, ETB_FFCR), 6) != 0
-				&& count > 0; count--)
-		udelay(1);
-	WARN(count == 0, "timeout while flushing ETB, ETB_FFCR: %#x\n",
-	     etb_readl(etb, ETB_FFCR));
-
-	etb_writel(etb, 0x0, ETB_CTL_REG);
-
-	for (count = TIMEOUT_US; BVAL(etb_readl(etb, ETB_FFSR), 1) != 1
-				&& count > 0; count--)
-		udelay(1);
-	WARN(count == 0, "timeout while disabling ETB, ETB_FFSR: %#x\n",
-	     etb_readl(etb, ETB_FFSR));
-
-	ETB_LOCK();
-}
-
-void etb_disable(void)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&etb.spinlock, flags);
-	__etb_disable();
-	etb.enabled = false;
-	dev_info(etb.dev, "ETB disabled\n");
-	spin_unlock_irqrestore(&etb.spinlock, flags);
-}
-
-static void __etb_dump(void)
-{
-	int i;
-	uint8_t *buf_ptr;
-	uint32_t read_data;
-	uint32_t read_ptr;
-	uint32_t write_ptr;
-	uint32_t frame_off;
-	uint32_t frame_endoff;
-
-	ETB_UNLOCK();
-
-	read_ptr = etb_readl(etb, ETB_RAM_READ_POINTER);
-	write_ptr = etb_readl(etb, ETB_RAM_WRITE_POINTER);
-
-	frame_off = write_ptr % FRAME_SIZE_WORDS;
-	frame_endoff = FRAME_SIZE_WORDS - frame_off;
-	if (frame_off) {
-		dev_err(etb.dev, "write_ptr: %lu not aligned to formatter "
-				"frame size\n", (unsigned long)write_ptr);
-		dev_err(etb.dev, "frameoff: %lu, frame_endoff: %lu\n",
-			(unsigned long)frame_off, (unsigned long)frame_endoff);
-		write_ptr += frame_endoff;
-	}
-
-	if ((etb_readl(etb, ETB_STATUS_REG) & BIT(0)) == 0)
-		etb_writel(etb, 0x0, ETB_RAM_READ_POINTER);
-	else
-		etb_writel(etb, write_ptr, ETB_RAM_READ_POINTER);
-
-	buf_ptr = etb.buf;
-	for (i = 0; i < ETB_SIZE_WORDS; i++) {
-		read_data = etb_readl(etb, ETB_RAM_READ_DATA_REG);
-		*buf_ptr++ = read_data >> 0;
-		*buf_ptr++ = read_data >> 8;
-		*buf_ptr++ = read_data >> 16;
-		*buf_ptr++ = read_data >> 24;
-	}
-
-	if (frame_off) {
-		buf_ptr -= (frame_endoff * BYTES_PER_WORD);
-		for (i = 0; i < frame_endoff; i++) {
-			*buf_ptr++ = 0x0;
-			*buf_ptr++ = 0x0;
-			*buf_ptr++ = 0x0;
-			*buf_ptr++ = 0x0;
-		}
-	}
-
-	etb_writel(etb, read_ptr, ETB_RAM_READ_POINTER);
-
-	ETB_LOCK();
-}
-
-void etb_dump(void)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&etb.spinlock, flags);
-	if (etb.enabled) {
-		__etb_disable();
-		__etb_dump();
-		__etb_enable();
-
-		dev_info(etb.dev, "ETB dumped\n");
-	}
-	spin_unlock_irqrestore(&etb.spinlock, flags);
-}
-
-static int etb_open(struct inode *inode, struct file *file)
-{
-	if (atomic_cmpxchg(&etb.in_use, 0, 1))
-		return -EBUSY;
-
-	dev_dbg(etb.dev, "%s: successfully opened\n", __func__);
-	return 0;
-}
-
-static ssize_t etb_read(struct file *file, char __user *data,
-				size_t len, loff_t *ppos)
-{
-	if (etb.reading == false) {
-		etb_dump();
-		etb.reading = true;
-	}
-
-	if (*ppos + len > ETB_SIZE_WORDS * BYTES_PER_WORD)
-		len = ETB_SIZE_WORDS * BYTES_PER_WORD - *ppos;
-
-	if (copy_to_user(data, etb.buf + *ppos, len)) {
-		dev_dbg(etb.dev, "%s: copy_to_user failed\n", __func__);
-		return -EFAULT;
-	}
-
-	*ppos += len;
-
-	dev_dbg(etb.dev, "%s: %d bytes copied, %d bytes left\n",
-		__func__, len, (int) (ETB_SIZE_WORDS * BYTES_PER_WORD - *ppos));
-
-	return len;
-}
-
-static int etb_release(struct inode *inode, struct file *file)
-{
-	etb.reading = false;
-
-	atomic_set(&etb.in_use, 0);
-
-	dev_dbg(etb.dev, "%s: released\n", __func__);
-
-	return 0;
-}
-
-static const struct file_operations etb_fops = {
-	.owner =	THIS_MODULE,
-	.open =		etb_open,
-	.read =		etb_read,
-	.release =	etb_release,
-};
-
-static struct miscdevice etb_misc = {
-	.name =		"msm_etb",
-	.minor =	MISC_DYNAMIC_MINOR,
-	.fops =		&etb_fops,
-};
-
-#define ETB_ATTR(__name)						\
-static struct kobj_attribute __name##_attr =				\
-	__ATTR(__name, S_IRUGO | S_IWUSR, __name##_show, __name##_store)
-
-static ssize_t trigger_cntr_store(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			const char *buf, size_t n)
-{
-	unsigned long val;
-
-	if (sscanf(buf, "%lx", &val) != 1)
-		return -EINVAL;
-
-	etb.trigger_cntr = val;
-	return n;
-}
-static ssize_t trigger_cntr_show(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			char *buf)
-{
-	unsigned long val = etb.trigger_cntr;
-	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
-}
-ETB_ATTR(trigger_cntr);
-
-static int __devinit etb_sysfs_init(void)
-{
-	int ret;
-
-	etb.kobj = kobject_create_and_add("etb", qdss_get_modulekobj());
-	if (!etb.kobj) {
-		dev_err(etb.dev, "failed to create ETB sysfs kobject\n");
-		ret = -ENOMEM;
-		goto err_create;
-	}
-
-	ret = sysfs_create_file(etb.kobj, &trigger_cntr_attr.attr);
-	if (ret) {
-		dev_err(etb.dev, "failed to create ETB sysfs trigger_cntr"
-		" attribute\n");
-		goto err_file;
-	}
-
-	return 0;
-err_file:
-	kobject_put(etb.kobj);
-err_create:
-	return ret;
-}
-
-static void __devexit etb_sysfs_exit(void)
-{
-	sysfs_remove_file(etb.kobj, &trigger_cntr_attr.attr);
-	kobject_put(etb.kobj);
-}
-
-static int __devinit etb_probe(struct platform_device *pdev)
-{
-	int ret;
-	struct resource *res;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		ret = -EINVAL;
-		goto err_res;
-	}
-
-	etb.base = ioremap_nocache(res->start, resource_size(res));
-	if (!etb.base) {
-		ret = -EINVAL;
-		goto err_ioremap;
-	}
-
-	etb.dev = &pdev->dev;
-
-	spin_lock_init(&etb.spinlock);
-
-	ret = misc_register(&etb_misc);
-	if (ret)
-		goto err_misc;
-
-	etb.buf = kzalloc(ETB_SIZE_WORDS * BYTES_PER_WORD, GFP_KERNEL);
-	if (!etb.buf) {
-		ret = -ENOMEM;
-		goto err_alloc;
-	}
-
-	etb_sysfs_init();
-
-	dev_info(etb.dev, "ETB initialized\n");
-	return 0;
-
-err_alloc:
-	misc_deregister(&etb_misc);
-err_misc:
-	iounmap(etb.base);
-err_ioremap:
-err_res:
-	dev_err(etb.dev, "ETB init failed\n");
-	return ret;
-}
-
-static int __devexit etb_remove(struct platform_device *pdev)
-{
-	if (etb.enabled)
-		etb_disable();
-	etb_sysfs_exit();
-	kfree(etb.buf);
-	misc_deregister(&etb_misc);
-	iounmap(etb.base);
-
-	return 0;
-}
-
-static struct of_device_id etb_match[] = {
-	{.compatible = "qcom,msm-etb"},
-	{}
-};
-
-static struct platform_driver etb_driver = {
-	.probe          = etb_probe,
-	.remove         = __devexit_p(etb_remove),
-	.driver         = {
-		.name   = "msm_etb",
-		.owner	= THIS_MODULE,
-		.of_match_table = etb_match,
-	},
-};
-
-static int __init etb_init(void)
-{
-	return platform_driver_register(&etb_driver);
-}
-module_init(etb_init);
-
-static void __exit etb_exit(void)
-{
-	platform_driver_unregister(&etb_driver);
-}
-module_exit(etb_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("CoreSight Embedded Trace Buffer driver");
diff --git a/arch/arm/mach-msm/qdss-etm.c b/arch/arm/mach-msm/qdss-etm.c
deleted file mode 100644
index e2a38de..0000000
--- a/arch/arm/mach-msm/qdss-etm.c
+++ /dev/null
@@ -1,1336 +0,0 @@
-/* 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
- * 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/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/err.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/smp.h>
-#include <linux/wakelock.h>
-#include <linux/pm_qos.h>
-#include <linux/sysfs.h>
-#include <linux/stat.h>
-#include <asm/sections.h>
-#include <mach/socinfo.h>
-
-#include "qdss-priv.h"
-
-#define etm_writel(etm, cpu, val, off)	\
-			__raw_writel((val), etm.base + (SZ_4K * cpu) + off)
-#define etm_readl(etm, cpu, off)	\
-			__raw_readl(etm.base + (SZ_4K * cpu) + off)
-
-/*
- * Device registers:
- * 0x000 - 0x2FC: Trace		registers
- * 0x300 - 0x314: Management	registers
- * 0x318 - 0xEFC: Trace		registers
- *
- * Coresight registers
- * 0xF00 - 0xF9C: Management	registers
- * 0xFA0 - 0xFA4: Management	registers in PFTv1.0
- *		  Trace		registers in PFTv1.1
- * 0xFA8 - 0xFFC: Management	registers
- */
-
-/* Trace registers (0x000-0x2FC) */
-#define ETMCR			(0x000)
-#define ETMCCR			(0x004)
-#define ETMTRIGGER		(0x008)
-#define ETMSR			(0x010)
-#define ETMSCR			(0x014)
-#define ETMTSSCR		(0x018)
-#define ETMTEEVR		(0x020)
-#define ETMTECR1		(0x024)
-#define ETMFFLR			(0x02C)
-#define ETMACVRn(n)		(0x040 + (n * 4))
-#define ETMACTRn(n)		(0x080 + (n * 4))
-#define ETMCNTRLDVRn(n)		(0x140 + (n * 4))
-#define ETMCNTENRn(n)		(0x150 + (n * 4))
-#define ETMCNTRLDEVRn(n)	(0x160 + (n * 4))
-#define ETMCNTVRn(n)		(0x170 + (n * 4))
-#define ETMSQ12EVR		(0x180)
-#define ETMSQ21EVR		(0x184)
-#define ETMSQ23EVR		(0x188)
-#define ETMSQ31EVR		(0x18C)
-#define ETMSQ32EVR		(0x190)
-#define ETMSQ13EVR		(0x194)
-#define ETMSQR			(0x19C)
-#define ETMEXTOUTEVRn(n)	(0x1A0 + (n * 4))
-#define ETMCIDCVRn(n)		(0x1B0 + (n * 4))
-#define ETMCIDCMR		(0x1BC)
-#define ETMIMPSPEC0		(0x1C0)
-#define ETMIMPSPEC1		(0x1C4)
-#define ETMIMPSPEC2		(0x1C8)
-#define ETMIMPSPEC3		(0x1CC)
-#define ETMIMPSPEC4		(0x1D0)
-#define ETMIMPSPEC5		(0x1D4)
-#define ETMIMPSPEC6		(0x1D8)
-#define ETMIMPSPEC7		(0x1DC)
-#define ETMSYNCFR		(0x1E0)
-#define ETMIDR			(0x1E4)
-#define ETMCCER			(0x1E8)
-#define ETMEXTINSELR		(0x1EC)
-#define ETMTESSEICR		(0x1F0)
-#define ETMEIBCR		(0x1F4)
-#define ETMTSEVR		(0x1F8)
-#define ETMAUXCR		(0x1FC)
-#define ETMTRACEIDR		(0x200)
-#define ETMVMIDCVR		(0x240)
-/* Management registers (0x300-0x314) */
-#define ETMOSLAR		(0x300)
-#define ETMOSLSR		(0x304)
-#define ETMOSSRR		(0x308)
-#define ETMPDCR			(0x310)
-#define ETMPDSR			(0x314)
-
-#define ETM_MAX_ADDR_CMP	(16)
-#define ETM_MAX_CNTR		(4)
-#define ETM_MAX_CTXID_CMP	(3)
-
-#define ETM_MODE_EXCLUDE	BIT(0)
-#define ETM_MODE_CYCACC		BIT(1)
-#define ETM_MODE_STALL		BIT(2)
-#define ETM_MODE_TIMESTAMP	BIT(3)
-#define ETM_MODE_CTXID		BIT(4)
-#define ETM_MODE_ALL		(0x1F)
-
-#define ETM_EVENT_MASK		(0x1FFFF)
-#define ETM_SYNC_MASK		(0xFFF)
-#define ETM_ALL_MASK		(0xFFFFFFFF)
-
-#define ETM_SEQ_STATE_MAX_VAL	(0x2)
-
-enum {
-	ETM_ADDR_TYPE_NONE,
-	ETM_ADDR_TYPE_SINGLE,
-	ETM_ADDR_TYPE_RANGE,
-	ETM_ADDR_TYPE_START,
-	ETM_ADDR_TYPE_STOP,
-};
-
-#define ETM_LOCK(cpu)							\
-do {									\
-	mb();								\
-	etm_writel(etm, cpu, 0x0, CS_LAR);				\
-} while (0)
-#define ETM_UNLOCK(cpu)							\
-do {									\
-	etm_writel(etm, cpu, CS_UNLOCK_MAGIC, CS_LAR);			\
-	mb();								\
-} while (0)
-
-
-#ifdef MODULE_PARAM_PREFIX
-#undef MODULE_PARAM_PREFIX
-#endif
-#define MODULE_PARAM_PREFIX "qdss."
-
-#ifdef CONFIG_MSM_QDSS_ETM_DEFAULT_ENABLE
-static int etm_boot_enable = 1;
-#else
-static int etm_boot_enable;
-#endif
-module_param_named(
-	etm_boot_enable, etm_boot_enable, int, S_IRUGO
-);
-
-struct etm_ctx {
-	void __iomem			*base;
-	bool				enabled;
-	struct wake_lock		wake_lock;
-	struct pm_qos_request		qos_req;
-	struct qdss_source		*src;
-	struct mutex			mutex;
-	struct device			*dev;
-	struct kobject			*kobj;
-	uint8_t				arch;
-	uint8_t				nr_addr_cmp;
-	uint8_t				nr_cntr;
-	uint8_t				nr_ext_inp;
-	uint8_t				nr_ext_out;
-	uint8_t				nr_ctxid_cmp;
-	uint8_t				reset;
-	uint32_t			mode;
-	uint32_t			ctrl;
-	uint32_t			trigger_event;
-	uint32_t			startstop_ctrl;
-	uint32_t			enable_event;
-	uint32_t			enable_ctrl1;
-	uint32_t			fifofull_level;
-	uint8_t				addr_idx;
-	uint32_t			addr_val[ETM_MAX_ADDR_CMP];
-	uint32_t			addr_acctype[ETM_MAX_ADDR_CMP];
-	uint32_t			addr_type[ETM_MAX_ADDR_CMP];
-	uint8_t				cntr_idx;
-	uint32_t			cntr_rld_val[ETM_MAX_CNTR];
-	uint32_t			cntr_event[ETM_MAX_CNTR];
-	uint32_t			cntr_rld_event[ETM_MAX_CNTR];
-	uint32_t			cntr_val[ETM_MAX_CNTR];
-	uint32_t			seq_12_event;
-	uint32_t			seq_21_event;
-	uint32_t			seq_23_event;
-	uint32_t			seq_31_event;
-	uint32_t			seq_32_event;
-	uint32_t			seq_13_event;
-	uint32_t			seq_curr_state;
-	uint8_t				ctxid_idx;
-	uint32_t			ctxid_val[ETM_MAX_CTXID_CMP];
-	uint32_t			ctxid_mask;
-	uint32_t			sync_freq;
-	uint32_t			timestamp_event;
-};
-
-static struct etm_ctx etm = {
-	.trigger_event		= 0x406F,
-	.enable_event		= 0x6F,
-	.enable_ctrl1		= 0x1,
-	.fifofull_level		= 0x28,
-	.addr_val		= {(uint32_t) _stext, (uint32_t) _etext},
-	.addr_type		= {ETM_ADDR_TYPE_RANGE, ETM_ADDR_TYPE_RANGE},
-	.cntr_event		= {[0 ... (ETM_MAX_CNTR - 1)] = 0x406F},
-	.cntr_rld_event		= {[0 ... (ETM_MAX_CNTR - 1)] = 0x406F},
-	.seq_12_event		= 0x406F,
-	.seq_21_event		= 0x406F,
-	.seq_23_event		= 0x406F,
-	.seq_31_event		= 0x406F,
-	.seq_32_event		= 0x406F,
-	.seq_13_event		= 0x406F,
-	.sync_freq		= 0x80,
-	.timestamp_event	= 0x406F,
-};
-
-
-/* ETM clock is derived from the processor clock and gets enabled on a
- * logical OR of below items on Krait (pass2 onwards):
- * 1.CPMR[ETMCLKEN] is 1
- * 2.ETMCR[PD] is 0
- * 3.ETMPDCR[PU] is 1
- * 4.Reset is asserted (core or debug)
- * 5.APB memory mapped requests (eg. EDAP access)
- *
- * 1., 2. and 3. above are permanent enables whereas 4. and 5. are temporary
- * enables
- *
- * We rely on 5. to be able to access ETMCR and then use 2. above for ETM
- * clock vote in the driver and the save-restore code uses 1. above
- * for its vote
- */
-static void etm_set_pwrdwn(int cpu)
-{
-	uint32_t etmcr;
-
-	etmcr = etm_readl(etm, cpu, ETMCR);
-	etmcr |= BIT(0);
-	etm_writel(etm, cpu, etmcr, ETMCR);
-}
-
-static void etm_clr_pwrdwn(int cpu)
-{
-	uint32_t etmcr;
-
-	etmcr = etm_readl(etm, cpu, ETMCR);
-	etmcr &= ~BIT(0);
-	etm_writel(etm, cpu, etmcr, ETMCR);
-}
-
-static void etm_set_prog(int cpu)
-{
-	uint32_t etmcr;
-	int count;
-
-	etmcr = etm_readl(etm, cpu, ETMCR);
-	etmcr |= BIT(10);
-	etm_writel(etm, cpu, etmcr, ETMCR);
-
-	for (count = TIMEOUT_US; BVAL(etm_readl(etm, cpu, ETMSR), 1) != 1
-				&& count > 0; count--)
-		udelay(1);
-	WARN(count == 0, "timeout while setting prog bit, ETMSR: %#x\n",
-	     etm_readl(etm, cpu, ETMSR));
-}
-
-static void etm_clr_prog(int cpu)
-{
-	uint32_t etmcr;
-	int count;
-
-	etmcr = etm_readl(etm, cpu, ETMCR);
-	etmcr &= ~BIT(10);
-	etm_writel(etm, cpu, etmcr, ETMCR);
-
-	for (count = TIMEOUT_US; BVAL(etm_readl(etm, cpu, ETMSR), 1) != 0
-				&& count > 0; count--)
-		udelay(1);
-	WARN(count == 0, "timeout while clearing prog bit, ETMSR: %#x\n",
-	     etm_readl(etm, cpu, ETMSR));
-}
-
-static void __etm_enable(int cpu)
-{
-	int i;
-
-	ETM_UNLOCK(cpu);
-	/* Vote for ETM power/clock enable */
-	etm_clr_pwrdwn(cpu);
-	etm_set_prog(cpu);
-
-	etm_writel(etm, cpu, etm.ctrl | BIT(10), ETMCR);
-	etm_writel(etm, cpu, etm.trigger_event, ETMTRIGGER);
-	etm_writel(etm, cpu, etm.startstop_ctrl, ETMTSSCR);
-	etm_writel(etm, cpu, etm.enable_event, ETMTEEVR);
-	etm_writel(etm, cpu, etm.enable_ctrl1, ETMTECR1);
-	etm_writel(etm, cpu, etm.fifofull_level, ETMFFLR);
-	for (i = 0; i < etm.nr_addr_cmp; i++) {
-		etm_writel(etm, cpu, etm.addr_val[i], ETMACVRn(i));
-		etm_writel(etm, cpu, etm.addr_acctype[i], ETMACTRn(i));
-	}
-	for (i = 0; i < etm.nr_cntr; i++) {
-		etm_writel(etm, cpu, etm.cntr_rld_val[i], ETMCNTRLDVRn(i));
-		etm_writel(etm, cpu, etm.cntr_event[i], ETMCNTENRn(i));
-		etm_writel(etm, cpu, etm.cntr_rld_event[i], ETMCNTRLDEVRn(i));
-		etm_writel(etm, cpu, etm.cntr_val[i], ETMCNTVRn(i));
-	}
-	etm_writel(etm, cpu, etm.seq_12_event, ETMSQ12EVR);
-	etm_writel(etm, cpu, etm.seq_21_event, ETMSQ21EVR);
-	etm_writel(etm, cpu, etm.seq_23_event, ETMSQ23EVR);
-	etm_writel(etm, cpu, etm.seq_31_event, ETMSQ31EVR);
-	etm_writel(etm, cpu, etm.seq_32_event, ETMSQ32EVR);
-	etm_writel(etm, cpu, etm.seq_13_event, ETMSQ13EVR);
-	etm_writel(etm, cpu, etm.seq_curr_state, ETMSQR);
-	for (i = 0; i < etm.nr_ext_out; i++)
-		etm_writel(etm, cpu, 0x0000406F, ETMEXTOUTEVRn(i));
-	for (i = 0; i < etm.nr_ctxid_cmp; i++)
-		etm_writel(etm, cpu, etm.ctxid_val[i], ETMCIDCVRn(i));
-	etm_writel(etm, cpu, etm.ctxid_mask, ETMCIDCMR);
-	etm_writel(etm, cpu, etm.sync_freq, ETMSYNCFR);
-	etm_writel(etm, cpu, 0x00000000, ETMEXTINSELR);
-	etm_writel(etm, cpu, etm.timestamp_event, ETMTSEVR);
-	etm_writel(etm, cpu, 0x00000000, ETMAUXCR);
-	etm_writel(etm, cpu, cpu+1, ETMTRACEIDR);
-	etm_writel(etm, cpu, 0x00000000, ETMVMIDCVR);
-
-	etm_clr_prog(cpu);
-	ETM_LOCK(cpu);
-}
-
-static int etm_enable(void)
-{
-	int ret, cpu;
-
-	if (etm.enabled) {
-		dev_err(etm.dev, "ETM tracing already enabled\n");
-		ret = -EPERM;
-		goto err;
-	}
-
-	wake_lock(&etm.wake_lock);
-	/* 1. causes all online cpus to come out of idle PC
-	 * 2. prevents idle PC until save restore flag is enabled atomically
-	 *
-	 * we rely on the user to prevent hotplug on/off racing with this
-	 * operation and to ensure cores where trace is expected to be turned
-	 * on are already hotplugged on
-	 */
-	pm_qos_update_request(&etm.qos_req, 0);
-
-	ret = qdss_enable(etm.src);
-	if (ret)
-		goto err_qdss;
-
-	for_each_online_cpu(cpu)
-		__etm_enable(cpu);
-
-	etm.enabled = true;
-
-	pm_qos_update_request(&etm.qos_req, PM_QOS_DEFAULT_VALUE);
-	wake_unlock(&etm.wake_lock);
-
-	dev_info(etm.dev, "ETM tracing enabled\n");
-	return 0;
-
-err_qdss:
-	pm_qos_update_request(&etm.qos_req, PM_QOS_DEFAULT_VALUE);
-	wake_unlock(&etm.wake_lock);
-err:
-	return ret;
-}
-
-static void __etm_disable(int cpu)
-{
-	ETM_UNLOCK(cpu);
-	etm_set_prog(cpu);
-
-	/* program trace enable to low by using always false event */
-	etm_writel(etm, cpu, 0x6F | BIT(14), ETMTEEVR);
-
-	/* Vote for ETM power/clock disable */
-	etm_set_pwrdwn(cpu);
-	ETM_LOCK(cpu);
-}
-
-static int etm_disable(void)
-{
-	int ret, cpu;
-
-	if (!etm.enabled) {
-		dev_err(etm.dev, "ETM tracing already disabled\n");
-		ret = -EPERM;
-		goto err;
-	}
-
-	wake_lock(&etm.wake_lock);
-	/* 1. causes all online cpus to come out of idle PC
-	 * 2. prevents idle PC until save restore flag is disabled atomically
-	 *
-	 * we rely on the user to prevent hotplug on/off racing with this
-	 * operation and to ensure cores where trace is expected to be turned
-	 * off are already hotplugged on
-	 */
-	pm_qos_update_request(&etm.qos_req, 0);
-
-	for_each_online_cpu(cpu)
-		__etm_disable(cpu);
-
-	qdss_disable(etm.src);
-
-	etm.enabled = false;
-
-	pm_qos_update_request(&etm.qos_req, PM_QOS_DEFAULT_VALUE);
-	wake_unlock(&etm.wake_lock);
-
-	dev_info(etm.dev, "ETM tracing disabled\n");
-	return 0;
-err:
-	return ret;
-}
-
-/* Memory mapped writes to clear os lock not supported */
-static void etm_os_unlock(void *unused)
-{
-	unsigned long value = 0x0;
-
-	asm("mcr p14, 1, %0, c1, c0, 4\n\t" : : "r" (value));
-	asm("isb\n\t");
-}
-
-#define ETM_STORE(__name, mask)						\
-static ssize_t __name##_store(struct kobject *kobj,			\
-			struct kobj_attribute *attr,			\
-			const char *buf, size_t n)			\
-{									\
-	unsigned long val;						\
-									\
-	if (sscanf(buf, "%lx", &val) != 1)				\
-		return -EINVAL;						\
-									\
-	etm.__name = val & mask;					\
-	return n;							\
-}
-
-#define ETM_SHOW(__name)						\
-static ssize_t __name##_show(struct kobject *kobj,			\
-			struct kobj_attribute *attr,			\
-			char *buf)					\
-{									\
-	unsigned long val = etm.__name;					\
-	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);		\
-}
-
-#define ETM_ATTR(__name)						\
-static struct kobj_attribute __name##_attr =				\
-	__ATTR(__name, S_IRUGO | S_IWUSR, __name##_show, __name##_store)
-#define ETM_ATTR_RO(__name)						\
-static struct kobj_attribute __name##_attr =				\
-	__ATTR(__name, S_IRUGO, __name##_show, NULL)
-
-static ssize_t enabled_store(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			const char *buf, size_t n)
-{
-	int ret = 0;
-	unsigned long val;
-
-	if (sscanf(buf, "%lx", &val) != 1)
-		return -EINVAL;
-
-	mutex_lock(&etm.mutex);
-	if (val)
-		ret = etm_enable();
-	else
-		ret = etm_disable();
-	mutex_unlock(&etm.mutex);
-
-	if (ret)
-		return ret;
-	return n;
-}
-ETM_SHOW(enabled);
-ETM_ATTR(enabled);
-
-ETM_SHOW(nr_addr_cmp);
-ETM_ATTR_RO(nr_addr_cmp);
-ETM_SHOW(nr_cntr);
-ETM_ATTR_RO(nr_cntr);
-ETM_SHOW(nr_ctxid_cmp);
-ETM_ATTR_RO(nr_ctxid_cmp);
-
-/* Reset to trace everything i.e. exclude nothing. */
-static ssize_t reset_store(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			const char *buf, size_t n)
-{
-	int i;
-	unsigned long val;
-
-	if (sscanf(buf, "%lx", &val) != 1)
-		return -EINVAL;
-
-	mutex_lock(&etm.mutex);
-	if (val) {
-		etm.mode = ETM_MODE_EXCLUDE;
-		etm.ctrl = 0x0;
-		if (cpu_is_krait_v1()) {
-			etm.mode |= ETM_MODE_CYCACC;
-			etm.ctrl |= BIT(12);
-		}
-		etm.trigger_event = 0x406F;
-		etm.startstop_ctrl = 0x0;
-		etm.enable_event = 0x6F;
-		etm.enable_ctrl1 = 0x1000000;
-		etm.fifofull_level = 0x28;
-		etm.addr_idx = 0x0;
-		for (i = 0; i < etm.nr_addr_cmp; i++) {
-			etm.addr_val[i] = 0x0;
-			etm.addr_acctype[i] = 0x0;
-			etm.addr_type[i] = ETM_ADDR_TYPE_NONE;
-		}
-		etm.cntr_idx = 0x0;
-		for (i = 0; i < etm.nr_cntr; i++) {
-			etm.cntr_rld_val[i] = 0x0;
-			etm.cntr_event[i] = 0x406F;
-			etm.cntr_rld_event[i] = 0x406F;
-			etm.cntr_val[i] = 0x0;
-		}
-		etm.seq_12_event = 0x406F;
-		etm.seq_21_event = 0x406F;
-		etm.seq_23_event = 0x406F;
-		etm.seq_31_event = 0x406F;
-		etm.seq_32_event = 0x406F;
-		etm.seq_13_event = 0x406F;
-		etm.seq_curr_state = 0x0;
-		etm.ctxid_idx = 0x0;
-		for (i = 0; i < etm.nr_ctxid_cmp; i++)
-			etm.ctxid_val[i] = 0x0;
-		etm.ctxid_mask = 0x0;
-		etm.sync_freq = 0x80;
-		etm.timestamp_event = 0x406F;
-	}
-	mutex_unlock(&etm.mutex);
-	return n;
-}
-ETM_SHOW(reset);
-ETM_ATTR(reset);
-
-static ssize_t mode_store(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			const char *buf, size_t n)
-{
-	unsigned long val;
-
-	if (sscanf(buf, "%lx", &val) != 1)
-		return -EINVAL;
-
-	mutex_lock(&etm.mutex);
-	etm.mode = val & ETM_MODE_ALL;
-
-	if (etm.mode & ETM_MODE_EXCLUDE)
-		etm.enable_ctrl1 |= BIT(24);
-	else
-		etm.enable_ctrl1 &= ~BIT(24);
-
-	if (etm.mode & ETM_MODE_CYCACC)
-		etm.ctrl |= BIT(12);
-	else
-		etm.ctrl &= ~BIT(12);
-
-	if (etm.mode & ETM_MODE_STALL)
-		etm.ctrl |= BIT(7);
-	else
-		etm.ctrl &= ~BIT(7);
-
-	if (etm.mode & ETM_MODE_TIMESTAMP)
-		etm.ctrl |= BIT(28);
-	else
-		etm.ctrl &= ~BIT(28);
-	if (etm.mode & ETM_MODE_CTXID)
-		etm.ctrl |= (BIT(14) | BIT(15));
-	else
-		etm.ctrl &= ~(BIT(14) | BIT(15));
-	mutex_unlock(&etm.mutex);
-
-	return n;
-}
-ETM_SHOW(mode);
-ETM_ATTR(mode);
-
-ETM_STORE(trigger_event, ETM_EVENT_MASK);
-ETM_SHOW(trigger_event);
-ETM_ATTR(trigger_event);
-
-ETM_STORE(enable_event, ETM_EVENT_MASK);
-ETM_SHOW(enable_event);
-ETM_ATTR(enable_event);
-
-ETM_STORE(fifofull_level, ETM_ALL_MASK);
-ETM_SHOW(fifofull_level);
-ETM_ATTR(fifofull_level);
-
-static ssize_t addr_idx_store(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			const char *buf, size_t n)
-{
-	unsigned long val;
-
-	if (sscanf(buf, "%lx", &val) != 1)
-		return -EINVAL;
-	if (val >= etm.nr_addr_cmp)
-		return -EINVAL;
-
-	/* Use mutex to ensure index doesn't change while it gets dereferenced
-	 * multiple times within a mutex block elsewhere.
-	 */
-	mutex_lock(&etm.mutex);
-	etm.addr_idx = val;
-	mutex_unlock(&etm.mutex);
-	return n;
-}
-ETM_SHOW(addr_idx);
-ETM_ATTR(addr_idx);
-
-static ssize_t addr_single_store(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			const char *buf, size_t n)
-{
-	unsigned long val;
-	uint8_t idx;
-
-	if (sscanf(buf, "%lx", &val) != 1)
-		return -EINVAL;
-
-	mutex_lock(&etm.mutex);
-	idx = etm.addr_idx;
-	if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
-	      etm.addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
-		mutex_unlock(&etm.mutex);
-		return -EPERM;
-	}
-
-	etm.addr_val[idx] = val;
-	etm.addr_type[idx] = ETM_ADDR_TYPE_SINGLE;
-	mutex_unlock(&etm.mutex);
-	return n;
-}
-static ssize_t addr_single_show(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			char *buf)
-{
-	unsigned long val;
-	uint8_t idx;
-
-	mutex_lock(&etm.mutex);
-	idx = etm.addr_idx;
-	if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
-	      etm.addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
-		mutex_unlock(&etm.mutex);
-		return -EPERM;
-	}
-
-	val = etm.addr_val[idx];
-	mutex_unlock(&etm.mutex);
-	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
-}
-ETM_ATTR(addr_single);
-
-static ssize_t addr_range_store(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			const char *buf, size_t n)
-{
-	unsigned long val1, val2;
-	uint8_t idx;
-
-	if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
-		return -EINVAL;
-	/* lower address comparator cannot have a higher address value */
-	if (val1 > val2)
-		return -EINVAL;
-
-	mutex_lock(&etm.mutex);
-	idx = etm.addr_idx;
-	if (idx % 2 != 0) {
-		mutex_unlock(&etm.mutex);
-		return -EPERM;
-	}
-	if (!((etm.addr_type[idx] == ETM_ADDR_TYPE_NONE &&
-	       etm.addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
-	      (etm.addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
-	       etm.addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
-		mutex_unlock(&etm.mutex);
-		return -EPERM;
-	}
-
-	etm.addr_val[idx] = val1;
-	etm.addr_type[idx] = ETM_ADDR_TYPE_RANGE;
-	etm.addr_val[idx + 1] = val2;
-	etm.addr_type[idx + 1] = ETM_ADDR_TYPE_RANGE;
-	etm.enable_ctrl1 |= (1 << (idx/2));
-	mutex_unlock(&etm.mutex);
-	return n;
-}
-static ssize_t addr_range_show(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			char *buf)
-{
-	unsigned long val1, val2;
-	uint8_t idx;
-
-	mutex_lock(&etm.mutex);
-	idx = etm.addr_idx;
-	if (idx % 2 != 0) {
-		mutex_unlock(&etm.mutex);
-		return -EPERM;
-	}
-	if (!((etm.addr_type[idx] == ETM_ADDR_TYPE_NONE &&
-	       etm.addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
-	      (etm.addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
-	       etm.addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
-		mutex_unlock(&etm.mutex);
-		return -EPERM;
-	}
-
-	val1 = etm.addr_val[idx];
-	val2 = etm.addr_val[idx + 1];
-	mutex_unlock(&etm.mutex);
-	return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
-}
-ETM_ATTR(addr_range);
-
-static ssize_t addr_start_store(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			const char *buf, size_t n)
-{
-	unsigned long val;
-	uint8_t idx;
-
-	if (sscanf(buf, "%lx", &val) != 1)
-		return -EINVAL;
-
-	mutex_lock(&etm.mutex);
-	idx = etm.addr_idx;
-	if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
-	      etm.addr_type[idx] == ETM_ADDR_TYPE_START)) {
-		mutex_unlock(&etm.mutex);
-		return -EPERM;
-	}
-
-	etm.addr_val[idx] = val;
-	etm.addr_type[idx] = ETM_ADDR_TYPE_START;
-	etm.startstop_ctrl |= (1 << idx);
-	etm.enable_ctrl1 |= BIT(25);
-	mutex_unlock(&etm.mutex);
-	return n;
-}
-static ssize_t addr_start_show(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			char *buf)
-{
-	unsigned long val;
-	uint8_t idx;
-
-	mutex_lock(&etm.mutex);
-	idx = etm.addr_idx;
-	if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
-	      etm.addr_type[idx] == ETM_ADDR_TYPE_START)) {
-		mutex_unlock(&etm.mutex);
-		return -EPERM;
-	}
-
-	val = etm.addr_val[idx];
-	mutex_unlock(&etm.mutex);
-	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
-}
-ETM_ATTR(addr_start);
-
-static ssize_t addr_stop_store(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			const char *buf, size_t n)
-{
-	unsigned long val;
-	uint8_t idx;
-
-	if (sscanf(buf, "%lx", &val) != 1)
-		return -EINVAL;
-
-	mutex_lock(&etm.mutex);
-	idx = etm.addr_idx;
-	if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
-	      etm.addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
-		mutex_unlock(&etm.mutex);
-		return -EPERM;
-	}
-
-	etm.addr_val[idx] = val;
-	etm.addr_type[idx] = ETM_ADDR_TYPE_STOP;
-	etm.startstop_ctrl |= (1 << (idx + 16));
-	etm.enable_ctrl1 |= BIT(25);
-	mutex_unlock(&etm.mutex);
-	return n;
-}
-static ssize_t addr_stop_show(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			char *buf)
-{
-	unsigned long val;
-	uint8_t idx;
-
-	mutex_lock(&etm.mutex);
-	idx = etm.addr_idx;
-	if (!(etm.addr_type[idx] == ETM_ADDR_TYPE_NONE ||
-	      etm.addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
-		mutex_unlock(&etm.mutex);
-		return -EPERM;
-	}
-
-	val = etm.addr_val[idx];
-	mutex_unlock(&etm.mutex);
-	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
-}
-ETM_ATTR(addr_stop);
-
-static ssize_t addr_acctype_store(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			const char *buf, size_t n)
-{
-	unsigned long val;
-
-	if (sscanf(buf, "%lx", &val) != 1)
-		return -EINVAL;
-
-	mutex_lock(&etm.mutex);
-	etm.addr_acctype[etm.addr_idx] = val;
-	mutex_unlock(&etm.mutex);
-	return n;
-}
-static ssize_t addr_acctype_show(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			char *buf)
-{
-	unsigned long val;
-
-	mutex_lock(&etm.mutex);
-	val = etm.addr_acctype[etm.addr_idx];
-	mutex_unlock(&etm.mutex);
-	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
-}
-ETM_ATTR(addr_acctype);
-
-static ssize_t cntr_idx_store(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			const char *buf, size_t n)
-{
-	unsigned long val;
-
-	if (sscanf(buf, "%lx", &val) != 1)
-		return -EINVAL;
-	if (val >= etm.nr_cntr)
-		return -EINVAL;
-
-	/* Use mutex to ensure index doesn't change while it gets dereferenced
-	 * multiple times within a mutex block elsewhere.
-	 */
-	mutex_lock(&etm.mutex);
-	etm.cntr_idx = val;
-	mutex_unlock(&etm.mutex);
-	return n;
-}
-ETM_SHOW(cntr_idx);
-ETM_ATTR(cntr_idx);
-
-static ssize_t cntr_rld_val_store(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			const char *buf, size_t n)
-{
-	unsigned long val;
-
-	if (sscanf(buf, "%lx", &val) != 1)
-		return -EINVAL;
-
-	mutex_lock(&etm.mutex);
-	etm.cntr_rld_val[etm.cntr_idx] = val;
-	mutex_unlock(&etm.mutex);
-	return n;
-}
-static ssize_t cntr_rld_val_show(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			char *buf)
-{
-	unsigned long val;
-	mutex_lock(&etm.mutex);
-	val = etm.cntr_rld_val[etm.cntr_idx];
-	mutex_unlock(&etm.mutex);
-	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
-}
-ETM_ATTR(cntr_rld_val);
-
-static ssize_t cntr_event_store(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			const char *buf, size_t n)
-{
-	unsigned long val;
-
-	if (sscanf(buf, "%lx", &val) != 1)
-		return -EINVAL;
-
-	mutex_lock(&etm.mutex);
-	etm.cntr_event[etm.cntr_idx] = val & ETM_EVENT_MASK;
-	mutex_unlock(&etm.mutex);
-	return n;
-}
-static ssize_t cntr_event_show(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			char *buf)
-{
-	unsigned long val;
-
-	mutex_lock(&etm.mutex);
-	val = etm.cntr_event[etm.cntr_idx];
-	mutex_unlock(&etm.mutex);
-	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
-}
-ETM_ATTR(cntr_event);
-
-static ssize_t cntr_rld_event_store(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			const char *buf, size_t n)
-{
-	unsigned long val;
-
-	if (sscanf(buf, "%lx", &val) != 1)
-		return -EINVAL;
-
-	mutex_lock(&etm.mutex);
-	etm.cntr_rld_event[etm.cntr_idx] = val & ETM_EVENT_MASK;
-	mutex_unlock(&etm.mutex);
-	return n;
-}
-static ssize_t cntr_rld_event_show(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			char *buf)
-{
-	unsigned long val;
-
-	mutex_lock(&etm.mutex);
-	val = etm.cntr_rld_event[etm.cntr_idx];
-	mutex_unlock(&etm.mutex);
-	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
-}
-ETM_ATTR(cntr_rld_event);
-
-static ssize_t cntr_val_store(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			const char *buf, size_t n)
-{
-	unsigned long val;
-
-	if (sscanf(buf, "%lx", &val) != 1)
-		return -EINVAL;
-
-	mutex_lock(&etm.mutex);
-	etm.cntr_val[etm.cntr_idx] = val;
-	mutex_unlock(&etm.mutex);
-	return n;
-}
-static ssize_t cntr_val_show(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			char *buf)
-{
-	unsigned long val;
-
-	mutex_lock(&etm.mutex);
-	val = etm.cntr_val[etm.cntr_idx];
-	mutex_unlock(&etm.mutex);
-	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
-}
-ETM_ATTR(cntr_val);
-
-ETM_STORE(seq_12_event, ETM_EVENT_MASK);
-ETM_SHOW(seq_12_event);
-ETM_ATTR(seq_12_event);
-
-ETM_STORE(seq_21_event, ETM_EVENT_MASK);
-ETM_SHOW(seq_21_event);
-ETM_ATTR(seq_21_event);
-
-ETM_STORE(seq_23_event, ETM_EVENT_MASK);
-ETM_SHOW(seq_23_event);
-ETM_ATTR(seq_23_event);
-
-ETM_STORE(seq_31_event, ETM_EVENT_MASK);
-ETM_SHOW(seq_31_event);
-ETM_ATTR(seq_31_event);
-
-ETM_STORE(seq_32_event, ETM_EVENT_MASK);
-ETM_SHOW(seq_32_event);
-ETM_ATTR(seq_32_event);
-
-ETM_STORE(seq_13_event, ETM_EVENT_MASK);
-ETM_SHOW(seq_13_event);
-ETM_ATTR(seq_13_event);
-
-static ssize_t seq_curr_state_store(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			const char *buf, size_t n)
-{
-	unsigned long val;
-
-	if (sscanf(buf, "%lx", &val) != 1)
-		return -EINVAL;
-	if (val > ETM_SEQ_STATE_MAX_VAL)
-		return -EINVAL;
-
-	etm.seq_curr_state = val;
-	return n;
-}
-ETM_SHOW(seq_curr_state);
-ETM_ATTR(seq_curr_state);
-
-static ssize_t ctxid_idx_store(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			const char *buf, size_t n)
-{
-	unsigned long val;
-
-	if (sscanf(buf, "%lx", &val) != 1)
-		return -EINVAL;
-	if (val >= etm.nr_ctxid_cmp)
-		return -EINVAL;
-
-	/* Use mutex to ensure index doesn't change while it gets dereferenced
-	 * multiple times within a mutex block elsewhere.
-	 */
-	mutex_lock(&etm.mutex);
-	etm.ctxid_idx = val;
-	mutex_unlock(&etm.mutex);
-	return n;
-}
-ETM_SHOW(ctxid_idx);
-ETM_ATTR(ctxid_idx);
-
-static ssize_t ctxid_val_store(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			const char *buf, size_t n)
-{
-	unsigned long val;
-
-	if (sscanf(buf, "%lx", &val) != 1)
-		return -EINVAL;
-
-	mutex_lock(&etm.mutex);
-	etm.ctxid_val[etm.ctxid_idx] = val;
-	mutex_unlock(&etm.mutex);
-	return n;
-}
-static ssize_t ctxid_val_show(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			char *buf)
-{
-	unsigned long val;
-
-	mutex_lock(&etm.mutex);
-	val = etm.ctxid_val[etm.ctxid_idx];
-	mutex_unlock(&etm.mutex);
-	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
-}
-ETM_ATTR(ctxid_val);
-
-ETM_STORE(ctxid_mask, ETM_ALL_MASK);
-ETM_SHOW(ctxid_mask);
-ETM_ATTR(ctxid_mask);
-
-ETM_STORE(sync_freq, ETM_SYNC_MASK);
-ETM_SHOW(sync_freq);
-ETM_ATTR(sync_freq);
-
-ETM_STORE(timestamp_event, ETM_EVENT_MASK);
-ETM_SHOW(timestamp_event);
-ETM_ATTR(timestamp_event);
-
-static struct attribute *etm_attrs[] = {
-	&nr_addr_cmp_attr.attr,
-	&nr_cntr_attr.attr,
-	&nr_ctxid_cmp_attr.attr,
-	&reset_attr.attr,
-	&mode_attr.attr,
-	&trigger_event_attr.attr,
-	&enable_event_attr.attr,
-	&fifofull_level_attr.attr,
-	&addr_idx_attr.attr,
-	&addr_single_attr.attr,
-	&addr_range_attr.attr,
-	&addr_start_attr.attr,
-	&addr_stop_attr.attr,
-	&addr_acctype_attr.attr,
-	&cntr_idx_attr.attr,
-	&cntr_rld_val_attr.attr,
-	&cntr_event_attr.attr,
-	&cntr_rld_event_attr.attr,
-	&cntr_val_attr.attr,
-	&seq_12_event_attr.attr,
-	&seq_21_event_attr.attr,
-	&seq_23_event_attr.attr,
-	&seq_31_event_attr.attr,
-	&seq_32_event_attr.attr,
-	&seq_13_event_attr.attr,
-	&seq_curr_state_attr.attr,
-	&ctxid_idx_attr.attr,
-	&ctxid_val_attr.attr,
-	&ctxid_mask_attr.attr,
-	&sync_freq_attr.attr,
-	&timestamp_event_attr.attr,
-	NULL,
-};
-
-static struct attribute_group etm_attr_grp = {
-	.attrs = etm_attrs,
-};
-
-static int __devinit etm_sysfs_init(void)
-{
-	int ret;
-
-	etm.kobj = kobject_create_and_add("etm", qdss_get_modulekobj());
-	if (!etm.kobj) {
-		dev_err(etm.dev, "failed to create ETM sysfs kobject\n");
-		ret = -ENOMEM;
-		goto err_create;
-	}
-
-	ret = sysfs_create_file(etm.kobj, &enabled_attr.attr);
-	if (ret) {
-		dev_err(etm.dev, "failed to create ETM sysfs enabled"
-		" attribute\n");
-		goto err_file;
-	}
-
-	if (sysfs_create_group(etm.kobj, &etm_attr_grp))
-		dev_err(etm.dev, "failed to create ETM sysfs group\n");
-
-	return 0;
-err_file:
-	kobject_put(etm.kobj);
-err_create:
-	return ret;
-}
-
-static void __devexit etm_sysfs_exit(void)
-{
-	sysfs_remove_group(etm.kobj, &etm_attr_grp);
-	sysfs_remove_file(etm.kobj, &enabled_attr.attr);
-	kobject_put(etm.kobj);
-}
-
-static bool __devinit etm_arch_supported(uint8_t arch)
-{
-	switch (arch) {
-	case PFT_ARCH_V1_1:
-		break;
-	default:
-		return false;
-	}
-	return true;
-}
-
-static int __devinit etm_arch_init(void)
-{
-	int ret, i;
-	/* use cpu 0 for setup */
-	int cpu = 0;
-	uint32_t etmidr;
-	uint32_t etmccr;
-
-	/* Unlock OS lock first to allow memory mapped reads and writes */
-	etm_os_unlock(NULL);
-	smp_call_function(etm_os_unlock, NULL, 1);
-	ETM_UNLOCK(cpu);
-	/* Vote for ETM power/clock enable */
-	etm_clr_pwrdwn(cpu);
-	/* Set prog bit. It will be set from reset but this is included to
-	 * ensure it is set
-	 */
-	etm_set_prog(cpu);
-
-	/* find all capabilities */
-	etmidr = etm_readl(etm, cpu, ETMIDR);
-	etm.arch = BMVAL(etmidr, 4, 11);
-	if (etm_arch_supported(etm.arch) == false) {
-		ret = -EINVAL;
-		goto err;
-	}
-
-	etmccr = etm_readl(etm, cpu, ETMCCR);
-	etm.nr_addr_cmp = BMVAL(etmccr, 0, 3) * 2;
-	etm.nr_cntr = BMVAL(etmccr, 13, 15);
-	etm.nr_ext_inp = BMVAL(etmccr, 17, 19);
-	etm.nr_ext_out = BMVAL(etmccr, 20, 22);
-	etm.nr_ctxid_cmp = BMVAL(etmccr, 24, 25);
-
-	if (cpu_is_krait_v1()) {
-		/* Krait pass1 doesn't support include filtering and non-cycle
-		 * accurate tracing
-		 */
-		etm.mode = (ETM_MODE_EXCLUDE | ETM_MODE_CYCACC);
-		etm.ctrl = 0x1000;
-		etm.enable_ctrl1 = 0x1000000;
-		for (i = 0; i < etm.nr_addr_cmp; i++) {
-			etm.addr_val[i] = 0x0;
-			etm.addr_acctype[i] = 0x0;
-			etm.addr_type[i] = ETM_ADDR_TYPE_NONE;
-		}
-	}
-
-	/* Vote for ETM power/clock disable */
-	etm_set_pwrdwn(cpu);
-	ETM_LOCK(cpu);
-
-	return 0;
-err:
-	return ret;
-}
-
-static int __devinit etm_probe(struct platform_device *pdev)
-{
-	int ret;
-	struct resource *res;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		ret = -EINVAL;
-		goto err_res;
-	}
-
-	etm.base = ioremap_nocache(res->start, resource_size(res));
-	if (!etm.base) {
-		ret = -EINVAL;
-		goto err_ioremap;
-	}
-
-	etm.dev = &pdev->dev;
-
-	mutex_init(&etm.mutex);
-	wake_lock_init(&etm.wake_lock, WAKE_LOCK_SUSPEND, "msm_etm");
-	pm_qos_add_request(&etm.qos_req, PM_QOS_CPU_DMA_LATENCY,
-						PM_QOS_DEFAULT_VALUE);
-	etm.src = qdss_get("msm_etm");
-	if (IS_ERR(etm.src)) {
-		ret = PTR_ERR(etm.src);
-		goto err_qdssget;
-	}
-
-	ret = qdss_clk_enable();
-	if (ret)
-		goto err_clk;
-
-	ret = etm_arch_init();
-	if (ret)
-		goto err_arch;
-
-	ret = etm_sysfs_init();
-	if (ret)
-		goto err_sysfs;
-
-	etm.enabled = false;
-
-	qdss_clk_disable();
-
-	dev_info(etm.dev, "ETM initialized\n");
-
-	if (etm_boot_enable)
-		etm_enable();
-
-	return 0;
-
-err_sysfs:
-err_arch:
-	qdss_clk_disable();
-err_clk:
-	qdss_put(etm.src);
-err_qdssget:
-	pm_qos_remove_request(&etm.qos_req);
-	wake_lock_destroy(&etm.wake_lock);
-	mutex_destroy(&etm.mutex);
-	iounmap(etm.base);
-err_ioremap:
-err_res:
-	dev_err(etm.dev, "ETM init failed\n");
-	return ret;
-}
-
-static int __devexit etm_remove(struct platform_device *pdev)
-{
-	if (etm.enabled)
-		etm_disable();
-	etm_sysfs_exit();
-	qdss_put(etm.src);
-	pm_qos_remove_request(&etm.qos_req);
-	wake_lock_destroy(&etm.wake_lock);
-	mutex_destroy(&etm.mutex);
-	iounmap(etm.base);
-
-	return 0;
-}
-
-static struct of_device_id etm_match[] = {
-	{.compatible = "qcom,msm-etm"},
-	{}
-};
-
-static struct platform_driver etm_driver = {
-	.probe          = etm_probe,
-	.remove         = __devexit_p(etm_remove),
-	.driver         = {
-		.name   = "msm_etm",
-		.owner	= THIS_MODULE,
-		.of_match_table = etm_match,
-	},
-};
-
-int __init etm_init(void)
-{
-	return platform_driver_register(&etm_driver);
-}
-module_init(etm_init);
-
-void __exit etm_exit(void)
-{
-	platform_driver_unregister(&etm_driver);
-}
-module_exit(etm_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("CoreSight Program Flow Trace driver");
diff --git a/arch/arm/mach-msm/qdss-funnel.c b/arch/arm/mach-msm/qdss-funnel.c
deleted file mode 100644
index 1c19ebd..0000000
--- a/arch/arm/mach-msm/qdss-funnel.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/* 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
- * 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/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/err.h>
-
-#include "qdss-priv.h"
-
-#define funnel_writel(funnel, id, val, off)	\
-			__raw_writel((val), funnel.base + (SZ_4K * id) + off)
-#define funnel_readl(funnel, id, off)		\
-			__raw_readl(funnel.base + (SZ_4K * id) + off)
-
-#define FUNNEL_FUNCTL			(0x000)
-#define FUNNEL_PRICTL			(0x004)
-#define FUNNEL_ITATBDATA0		(0xEEC)
-#define FUNNEL_ITATBCTR2		(0xEF0)
-#define FUNNEL_ITATBCTR1		(0xEF4)
-#define FUNNEL_ITATBCTR0		(0xEF8)
-
-
-#define FUNNEL_LOCK(id)							\
-do {									\
-	mb();								\
-	funnel_writel(funnel, id, 0x0, CS_LAR);				\
-} while (0)
-#define FUNNEL_UNLOCK(id)						\
-do {									\
-	funnel_writel(funnel, id, CS_UNLOCK_MAGIC, CS_LAR);		\
-	mb();								\
-} while (0)
-
-#define FUNNEL_HOLDTIME_MASK		(0xF00)
-#define FUNNEL_HOLDTIME_SHFT		(0x8)
-#define FUNNEL_HOLDTIME			(0x7 << FUNNEL_HOLDTIME_SHFT)
-
-struct funnel_ctx {
-	void __iomem	*base;
-	bool		enabled;
-	struct mutex	mutex;
-	struct device	*dev;
-	struct kobject	*kobj;
-	uint32_t	priority;
-};
-
-static struct funnel_ctx funnel;
-
-static void __funnel_enable(uint8_t id, uint32_t port_mask)
-{
-	uint32_t functl;
-
-	FUNNEL_UNLOCK(id);
-
-	functl = funnel_readl(funnel, id, FUNNEL_FUNCTL);
-	functl &= ~FUNNEL_HOLDTIME_MASK;
-	functl |= FUNNEL_HOLDTIME;
-	functl |= port_mask;
-	funnel_writel(funnel, id, functl, FUNNEL_FUNCTL);
-	funnel_writel(funnel, id, funnel.priority, FUNNEL_PRICTL);
-
-	FUNNEL_LOCK(id);
-}
-
-void funnel_enable(uint8_t id, uint32_t port_mask)
-{
-	mutex_lock(&funnel.mutex);
-	__funnel_enable(id, port_mask);
-	funnel.enabled = true;
-	dev_info(funnel.dev, "FUNNEL port mask 0x%lx enabled\n",
-					(unsigned long) port_mask);
-	mutex_unlock(&funnel.mutex);
-}
-
-static void __funnel_disable(uint8_t id, uint32_t port_mask)
-{
-	uint32_t functl;
-
-	FUNNEL_UNLOCK(id);
-
-	functl = funnel_readl(funnel, id, FUNNEL_FUNCTL);
-	functl &= ~port_mask;
-	funnel_writel(funnel, id, functl, FUNNEL_FUNCTL);
-
-	FUNNEL_LOCK(id);
-}
-
-void funnel_disable(uint8_t id, uint32_t port_mask)
-{
-	mutex_lock(&funnel.mutex);
-	__funnel_disable(id, port_mask);
-	funnel.enabled = false;
-	dev_info(funnel.dev, "FUNNEL port mask 0x%lx disabled\n",
-					(unsigned long) port_mask);
-	mutex_unlock(&funnel.mutex);
-}
-
-#define FUNNEL_ATTR(__name)						\
-static struct kobj_attribute __name##_attr =				\
-	__ATTR(__name, S_IRUGO | S_IWUSR, __name##_show, __name##_store)
-
-static ssize_t priority_store(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			const char *buf, size_t n)
-{
-	unsigned long val;
-
-	if (sscanf(buf, "%lx", &val) != 1)
-		return -EINVAL;
-
-	funnel.priority = val;
-	return n;
-}
-static ssize_t priority_show(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			char *buf)
-{
-	unsigned long val = funnel.priority;
-	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
-}
-FUNNEL_ATTR(priority);
-
-static int __devinit funnel_sysfs_init(void)
-{
-	int ret;
-
-	funnel.kobj = kobject_create_and_add("funnel", qdss_get_modulekobj());
-	if (!funnel.kobj) {
-		dev_err(funnel.dev, "failed to create FUNNEL sysfs kobject\n");
-		ret = -ENOMEM;
-		goto err_create;
-	}
-
-	ret = sysfs_create_file(funnel.kobj, &priority_attr.attr);
-	if (ret) {
-		dev_err(funnel.dev, "failed to create FUNNEL sysfs priority"
-		" attribute\n");
-		goto err_file;
-	}
-
-	return 0;
-err_file:
-	kobject_put(funnel.kobj);
-err_create:
-	return ret;
-}
-
-static void __devexit funnel_sysfs_exit(void)
-{
-	sysfs_remove_file(funnel.kobj, &priority_attr.attr);
-	kobject_put(funnel.kobj);
-}
-
-static int __devinit funnel_probe(struct platform_device *pdev)
-{
-	int ret;
-	struct resource *res;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		ret = -EINVAL;
-		goto err_res;
-	}
-
-	funnel.base = ioremap_nocache(res->start, resource_size(res));
-	if (!funnel.base) {
-		ret = -EINVAL;
-		goto err_ioremap;
-	}
-
-	funnel.dev = &pdev->dev;
-
-	mutex_init(&funnel.mutex);
-
-	funnel_sysfs_init();
-
-	dev_info(funnel.dev, "FUNNEL initialized\n");
-	return 0;
-
-err_ioremap:
-err_res:
-	dev_err(funnel.dev, "FUNNEL init failed\n");
-	return ret;
-}
-
-static int __devexit funnel_remove(struct platform_device *pdev)
-{
-	if (funnel.enabled)
-		funnel_disable(0x0, 0xFF);
-	funnel_sysfs_exit();
-	mutex_destroy(&funnel.mutex);
-	iounmap(funnel.base);
-
-	return 0;
-}
-
-static struct of_device_id funnel_match[] = {
-	{.compatible = "qcom,msm-funnel"},
-	{}
-};
-
-static struct platform_driver funnel_driver = {
-	.probe          = funnel_probe,
-	.remove         = __devexit_p(funnel_remove),
-	.driver         = {
-		.name   = "msm_funnel",
-		.owner	= THIS_MODULE,
-		.of_match_table = funnel_match,
-	},
-};
-
-static int __init funnel_init(void)
-{
-	return platform_driver_register(&funnel_driver);
-}
-module_init(funnel_init);
-
-static void __exit funnel_exit(void)
-{
-	platform_driver_unregister(&funnel_driver);
-}
-module_exit(funnel_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("CoreSight Funnel driver");
diff --git a/arch/arm/mach-msm/qdss-priv.h b/arch/arm/mach-msm/qdss-priv.h
deleted file mode 100644
index f39bc52..0000000
--- a/arch/arm/mach-msm/qdss-priv.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* 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
- * 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 _ARCH_ARM_MACH_MSM_QDSS_H_
-#define _ARCH_ARM_MACH_MSM_QDSS_H_
-
-#include <linux/bitops.h>
-#include <mach/qdss.h>
-
-/* Coresight management registers (0xF00-0xFCC)
- * 0xFA0 - 0xFA4: Management	registers in PFTv1.0
- *		  Trace		registers in PFTv1.1
- */
-#define CS_ITCTRL		(0xF00)
-#define CS_CLAIMSET		(0xFA0)
-#define CS_CLAIMCLR		(0xFA4)
-#define CS_LAR			(0xFB0)
-#define CS_LSR			(0xFB4)
-#define CS_AUTHSTATUS		(0xFB8)
-#define CS_DEVID		(0xFC8)
-#define CS_DEVTYPE		(0xFCC)
-/* Peripheral id registers (0xFD0-0xFEC) */
-#define CS_PIDR4		(0xFD0)
-#define CS_PIDR5		(0xFD4)
-#define CS_PIDR6		(0xFD8)
-#define CS_PIDR7		(0xFDC)
-#define CS_PIDR0		(0xFE0)
-#define CS_PIDR1		(0xFE4)
-#define CS_PIDR2		(0xFE8)
-#define CS_PIDR3		(0xFEC)
-/* Component id registers (0xFF0-0xFFC) */
-#define CS_CIDR0		(0xFF0)
-#define CS_CIDR1		(0xFF4)
-#define CS_CIDR2		(0xFF8)
-#define CS_CIDR3		(0xFFC)
-
-/* DBGv7 with baseline CP14 registers implemented */
-#define ARM_DEBUG_ARCH_V7B	(0x3)
-/* DBGv7 with all CP14 registers implemented */
-#define ARM_DEBUG_ARCH_V7	(0x4)
-#define ARM_DEBUG_ARCH_V7_1	(0x5)
-#define ETM_ARCH_V3_3		(0x23)
-#define PFT_ARCH_V1_1		(0x31)
-
-#define TIMEOUT_US		(100)
-#define CS_UNLOCK_MAGIC		(0xC5ACCE55)
-
-#define BM(lsb, msb)		((BIT(msb) - BIT(lsb)) + BIT(msb))
-#define BMVAL(val, lsb, msb)	((val & BM(lsb, msb)) >> lsb)
-#define BVAL(val, n)		((val & BIT(n)) >> n)
-
-void etb_enable(void);
-void etb_disable(void);
-void etb_dump(void);
-void tpiu_disable(void);
-void funnel_enable(uint8_t id, uint32_t port_mask);
-void funnel_disable(uint8_t id, uint32_t port_mask);
-
-struct kobject *qdss_get_modulekobj(void);
-
-#endif
diff --git a/arch/arm/mach-msm/qdss.c b/arch/arm/mach-msm/qdss.c
deleted file mode 100644
index 83a6a36..0000000
--- a/arch/arm/mach-msm/qdss.c
+++ /dev/null
@@ -1,411 +0,0 @@
-/* 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/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/err.h>
-#include <linux/export.h>
-#include <mach/rpm.h>
-
-#include "rpm_resources.h"
-#include "qdss-priv.h"
-
-#define MAX_STR_LEN	(65535)
-
-enum {
-	QDSS_CLK_OFF,
-	QDSS_CLK_ON_DBG,
-	QDSS_CLK_ON_HSDBG,
-};
-
-/*
- * Exclusion rules for structure fields.
- *
- * S: qdss.sources_mutex protected.
- * I: qdss.sink_mutex protected.
- * C: qdss.clk_mutex protected.
- */
-struct qdss_ctx {
-	struct kobject			*modulekobj;
-	uint8_t				afamily;
-	struct list_head		sources;	/* S: sources list */
-	struct mutex			sources_mutex;
-	uint8_t				sink_count;	/* I: sink count */
-	struct mutex			sink_mutex;
-	uint8_t				max_clk;
-	uint8_t				clk_count;	/* C: clk count */
-	struct mutex			clk_mutex;
-};
-
-static struct qdss_ctx qdss;
-
-/**
- * qdss_get - get the qdss source handle
- * @name: name of the qdss source
- *
- * Searches the sources list to get the qdss source handle for this source.
- *
- * CONTEXT:
- * Typically called from init or probe functions
- *
- * RETURNS:
- * pointer to struct qdss_source on success, %NULL on failure
- */
-struct qdss_source *qdss_get(const char *name)
-{
-	struct qdss_source *src, *source = NULL;
-
-	mutex_lock(&qdss.sources_mutex);
-	list_for_each_entry(src, &qdss.sources, link) {
-		if (src->name) {
-			if (strncmp(src->name, name, MAX_STR_LEN))
-				continue;
-			source = src;
-			break;
-		}
-	}
-	mutex_unlock(&qdss.sources_mutex);
-
-	return source ? source : ERR_PTR(-ENOENT);
-}
-EXPORT_SYMBOL(qdss_get);
-
-/**
- * qdss_put - release the qdss source handle
- * @name: name of the qdss source
- *
- * CONTEXT:
- * Typically called from driver remove or exit functions
- */
-void qdss_put(struct qdss_source *src)
-{
-}
-EXPORT_SYMBOL(qdss_put);
-
-/**
- * qdss_enable - enable qdss for the source
- * @src: handle for the source making the call
- *
- * Enables qdss block (relevant funnel ports and sink) if not already
- * enabled, otherwise increments the reference count
- *
- * CONTEXT:
- * Might sleep. Uses a mutex lock. Should be called from a non-atomic context.
- *
- * RETURNS:
- * 0 on success, non-zero on failure
- */
-int qdss_enable(struct qdss_source *src)
-{
-	int ret;
-
-	if (!src)
-		return -EINVAL;
-
-	ret = qdss_clk_enable();
-	if (ret)
-		goto err;
-
-	if (qdss.afamily) {
-		mutex_lock(&qdss.sink_mutex);
-		if (qdss.sink_count == 0) {
-			etb_disable();
-			tpiu_disable();
-			/* enable ETB first to avoid losing any trace data */
-			etb_enable();
-		}
-		qdss.sink_count++;
-		mutex_unlock(&qdss.sink_mutex);
-	}
-
-	funnel_enable(0x0, src->fport_mask);
-	return 0;
-err:
-	return ret;
-}
-EXPORT_SYMBOL(qdss_enable);
-
-/**
- * qdss_disable - disable qdss for the source
- * @src: handle for the source making the call
- *
- * Disables qdss block (relevant funnel ports and sink) if the reference count
- * is one, otherwise decrements the reference count
- *
- * CONTEXT:
- * Might sleep. Uses a mutex lock. Should be called from a non-atomic context.
- */
-void qdss_disable(struct qdss_source *src)
-{
-	if (!src)
-		return;
-
-	if (qdss.afamily) {
-		mutex_lock(&qdss.sink_mutex);
-		if (WARN(qdss.sink_count == 0, "qdss is unbalanced\n"))
-			goto out;
-		if (qdss.sink_count == 1) {
-			etb_dump();
-			etb_disable();
-		}
-		qdss.sink_count--;
-		mutex_unlock(&qdss.sink_mutex);
-	}
-
-	funnel_disable(0x0, src->fport_mask);
-	qdss_clk_disable();
-	return;
-out:
-	mutex_unlock(&qdss.sink_mutex);
-}
-EXPORT_SYMBOL(qdss_disable);
-
-/**
- * qdss_disable_sink - force disable the current qdss sink(s)
- *
- * Force disable the current qdss sink(s) to stop the sink from accepting any
- * trace generated subsequent to this call. This function should only be used
- * as a way to stop the sink from getting polluted with trace data that is
- * uninteresting after an event of interest has occured.
- *
- * CONTEXT:
- * Can be called from atomic or non-atomic context.
- */
-void qdss_disable_sink(void)
-{
-	if (qdss.afamily) {
-		etb_dump();
-		etb_disable();
-	}
-}
-EXPORT_SYMBOL(qdss_disable_sink);
-
-/**
- * qdss_clk_enable - enable qdss clocks
- *
- * Enables qdss clocks via RPM if they aren't already enabled, otherwise
- * increments the reference count.
- *
- * CONTEXT:
- * Might sleep. Uses a mutex lock. Should be called from a non-atomic context.
- *
- * RETURNS:
- * 0 on success, non-zero on failure
- */
-int qdss_clk_enable(void)
-{
-	int ret;
-	struct msm_rpm_iv_pair iv;
-
-	mutex_lock(&qdss.clk_mutex);
-	if (qdss.clk_count == 0) {
-		iv.id = MSM_RPM_ID_QDSS_CLK;
-		if (qdss.max_clk)
-			iv.value = QDSS_CLK_ON_HSDBG;
-		else
-			iv.value = QDSS_CLK_ON_DBG;
-		ret = msm_rpmrs_set(MSM_RPM_CTX_SET_0, &iv, 1);
-		if (WARN(ret, "qdss clks not enabled (%d)\n", ret))
-			goto err_clk;
-	}
-	qdss.clk_count++;
-	mutex_unlock(&qdss.clk_mutex);
-	return 0;
-err_clk:
-	mutex_unlock(&qdss.clk_mutex);
-	return ret;
-}
-EXPORT_SYMBOL(qdss_clk_enable);
-
-/**
- * qdss_clk_disable - disable qdss clocks
- *
- * Disables qdss clocks via RPM if the reference count is one, otherwise
- * decrements the reference count.
- *
- * CONTEXT:
- * Might sleep. Uses a mutex lock. Should be called from a non-atomic context.
- */
-void qdss_clk_disable(void)
-{
-	int ret;
-	struct msm_rpm_iv_pair iv;
-
-	mutex_lock(&qdss.clk_mutex);
-	if (WARN(qdss.clk_count == 0, "qdss clks are unbalanced\n"))
-		goto out;
-	if (qdss.clk_count == 1) {
-		iv.id = MSM_RPM_ID_QDSS_CLK;
-		iv.value = QDSS_CLK_OFF;
-		ret = msm_rpmrs_set(MSM_RPM_CTX_SET_0, &iv, 1);
-		WARN(ret, "qdss clks not disabled (%d)\n", ret);
-	}
-	qdss.clk_count--;
-out:
-	mutex_unlock(&qdss.clk_mutex);
-}
-EXPORT_SYMBOL(qdss_clk_disable);
-
-struct kobject *qdss_get_modulekobj(void)
-{
-	return qdss.modulekobj;
-}
-
-#define QDSS_ATTR(name)						\
-static struct kobj_attribute name##_attr =				\
-		__ATTR(name, S_IRUGO | S_IWUSR, name##_show, name##_store)
-
-static ssize_t max_clk_store(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			const char *buf, size_t n)
-{
-	unsigned long val;
-
-	if (sscanf(buf, "%lx", &val) != 1)
-		return -EINVAL;
-
-	qdss.max_clk = val;
-	return n;
-}
-static ssize_t max_clk_show(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			char *buf)
-{
-	unsigned long val = qdss.max_clk;
-	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
-}
-QDSS_ATTR(max_clk);
-
-static void __devinit qdss_add_sources(struct qdss_source *srcs, size_t num)
-{
-	mutex_lock(&qdss.sources_mutex);
-	while (num--) {
-		list_add_tail(&srcs->link, &qdss.sources);
-		srcs++;
-	}
-	mutex_unlock(&qdss.sources_mutex);
-}
-
-static int __init qdss_sysfs_init(void)
-{
-	int ret;
-
-	qdss.modulekobj = kset_find_obj(module_kset, KBUILD_MODNAME);
-	if (!qdss.modulekobj) {
-		pr_err("failed to find QDSS sysfs module kobject\n");
-		ret = -ENOENT;
-		goto err;
-	}
-
-	ret = sysfs_create_file(qdss.modulekobj, &max_clk_attr.attr);
-	if (ret) {
-		pr_err("failed to create QDSS sysfs max_clk attribute\n");
-		goto err;
-	}
-
-	return 0;
-err:
-	return ret;
-}
-
-static void __devexit qdss_sysfs_exit(void)
-{
-	sysfs_remove_file(qdss.modulekobj, &max_clk_attr.attr);
-}
-
-static int __devinit qdss_probe(struct platform_device *pdev)
-{
-	int ret;
-	struct msm_qdss_platform_data *pdata;
-
-	mutex_init(&qdss.sources_mutex);
-	mutex_init(&qdss.clk_mutex);
-	mutex_init(&qdss.sink_mutex);
-
-	INIT_LIST_HEAD(&qdss.sources);
-
-	pdata = pdev->dev.platform_data;
-	if (!pdata)
-		goto err_pdata;
-
-	qdss.afamily = pdata->afamily;
-	qdss_add_sources(pdata->src_table, pdata->size);
-
-	pr_info("QDSS arch initialized\n");
-	return 0;
-err_pdata:
-	mutex_destroy(&qdss.sink_mutex);
-	mutex_destroy(&qdss.clk_mutex);
-	mutex_destroy(&qdss.sources_mutex);
-	pr_err("QDSS init failed\n");
-	return ret;
-}
-
-static int __devexit qdss_remove(struct platform_device *pdev)
-{
-	qdss_sysfs_exit();
-	mutex_destroy(&qdss.sink_mutex);
-	mutex_destroy(&qdss.clk_mutex);
-	mutex_destroy(&qdss.sources_mutex);
-
-	return 0;
-}
-
-static struct of_device_id qdss_match[] = {
-	{.compatible = "qcom,msm-qdss"},
-	{}
-};
-
-static struct platform_driver qdss_driver = {
-	.probe          = qdss_probe,
-	.remove         = __devexit_p(qdss_remove),
-	.driver         = {
-		.name   = "msm_qdss",
-		.owner	= THIS_MODULE,
-		.of_match_table = qdss_match,
-	},
-};
-
-static int __init qdss_init(void)
-{
-	return platform_driver_register(&qdss_driver);
-}
-arch_initcall(qdss_init);
-
-static int __init qdss_module_init(void)
-{
-	int ret;
-
-	ret = qdss_sysfs_init();
-	if (ret)
-		goto err_sysfs;
-
-	pr_info("QDSS module initialized\n");
-	return 0;
-err_sysfs:
-	return ret;
-}
-module_init(qdss_module_init);
-
-static void __exit qdss_exit(void)
-{
-	platform_driver_unregister(&qdss_driver);
-}
-module_exit(qdss_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Qualcomm Debug SubSystem Driver");
diff --git a/arch/arm/mach-msm/sdio_ctl.c b/arch/arm/mach-msm/sdio_ctl.c
index 586e890..ac16e77 100644
--- a/arch/arm/mach-msm/sdio_ctl.c
+++ b/arch/arm/mach-msm/sdio_ctl.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
@@ -25,6 +25,7 @@
 #include <linux/mutex.h>
 #include <linux/uaccess.h>
 #include <linux/workqueue.h>
+#include <linux/poll.h>
 #include <asm/ioctls.h>
 #include <linux/platform_device.h>
 #include <mach/msm_smd.h>
@@ -206,6 +207,34 @@
 	return ret;
 }
 
+static unsigned int sdio_ctl_poll(struct file *file, poll_table *wait)
+{
+	struct sdio_ctl_dev *sdio_ctl_devp;
+	unsigned int mask = 0;
+
+	sdio_ctl_devp = file->private_data;
+	if (!sdio_ctl_devp) {
+		pr_err("%s: on a NULL device\n", __func__);
+		return POLLERR;
+	}
+
+	poll_wait(file, &sdio_ctl_devp->read_wait_queue, wait);
+	mutex_lock(&sdio_ctl_devp->rx_lock);
+	if (sdio_cmux_is_channel_reset(sdio_ctl_devp->id)) {
+		mutex_unlock(&sdio_ctl_devp->rx_lock);
+		pr_err("%s notifying reset for sdio_ctl_dev id:%d\n",
+			__func__, sdio_ctl_devp->id);
+		return POLLERR;
+	}
+
+	if (sdio_ctl_devp->read_avail > 0)
+		mask |= POLLIN | POLLRDNORM;
+
+	mutex_unlock(&sdio_ctl_devp->rx_lock);
+
+	return mask;
+}
+
 ssize_t sdio_ctl_read(struct file *file,
 		      char __user *buf,
 		      size_t count,
@@ -417,6 +446,7 @@
 	.release = sdio_ctl_release,
 	.read = sdio_ctl_read,
 	.write = sdio_ctl_write,
+	.poll = sdio_ctl_poll,
 	.unlocked_ioctl = sdio_ctl_ioctl,
 };
 
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index b047cf4..533e6cd 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.c
@@ -189,12 +189,14 @@
 	[88] = MSM_CPU_7X25A,
 	[89] = MSM_CPU_7X25A,
 	[96] = MSM_CPU_7X25A,
+	[135] = MSM_CPU_7X25A,
 
 	/* 7x27A IDs */
 	[90] = MSM_CPU_7X27A,
 	[91] = MSM_CPU_7X27A,
 	[92] = MSM_CPU_7X27A,
 	[97] = MSM_CPU_7X27A,
+	[136] = MSM_CPU_7X27A,
 
 	/* FSM9xxx ID */
 	[94] = FSM_CPU_9XXX,
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 286a4d4..a73d713 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -148,4 +148,6 @@
 
 source "drivers/gud/Kconfig"
 
+source "drivers/coresight/Kconfig"
+
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index bea505c..bd18a62 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -140,3 +140,5 @@
 
 #MobiCore
 obj-$(CONFIG_MOBICORE_SUPPORT)  += gud/
+
+obj-$(CONFIG_MSM_QDSS)		+= coresight/
diff --git a/drivers/coresight/Kconfig b/drivers/coresight/Kconfig
new file mode 100644
index 0000000..1219af1
--- /dev/null
+++ b/drivers/coresight/Kconfig
@@ -0,0 +1,32 @@
+config MSM_QDSS
+	bool "CoreSight tracing"
+	help
+	  Enables support for CoreSight tracing. This uses CoreSight trace
+	  components and buses to support both hardware (eg. processor ETM)
+	  and hardware assisted software instrumentation based (eg. STM)
+	  tracing.
+
+	  For production builds, you should probably say 'N' here to avoid
+	  potential power, performance and memory penalty.
+
+config MSM_QDSS_STM_DEFAULT_ENABLE
+	bool "Turn on CoreSight STM tracing by default"
+	depends on MSM_QDSS
+	help
+	  Turns on CoreSight STM tracing (hardware assisted software
+	  instrumentation based tracing) by default. Otherwise, tracing is
+	  disabled by default but can be enabled via sysfs.
+
+	  For production builds, you should probably say 'N' here to avoid
+	  potential power, performance and memory penalty.
+
+config MSM_QDSS_ETM_DEFAULT_ENABLE
+	bool "Turn on CoreSight ETM tracing by default"
+	depends on MSM_QDSS
+	help
+	  Turns on CoreSight ETM tracing (processor tracing) by default.
+	  Otherwise, tracing is disabled by default but can be enabled via
+	  sysfs.
+
+	  For production builds, you should probably say 'N' here to avoid
+	  potential power, performance and memory penalty.
diff --git a/drivers/coresight/Makefile b/drivers/coresight/Makefile
new file mode 100644
index 0000000..2ee2093
--- /dev/null
+++ b/drivers/coresight/Makefile
@@ -0,0 +1,2 @@
+
+obj-$(CONFIG_MSM_QDSS) += coresight.o coresight-etb.o coresight-tpiu.o coresight-funnel.o coresight-stm.o coresight-etm.o
diff --git a/drivers/coresight/coresight-etb.c b/drivers/coresight/coresight-etb.c
new file mode 100644
index 0000000..2bffae5
--- /dev/null
+++ b/drivers/coresight/coresight-etb.c
@@ -0,0 +1,451 @@
+/* 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
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/clk.h>
+#include <linux/coresight.h>
+
+#include "coresight-priv.h"
+
+#define etb_writel(drvdata, val, off)	__raw_writel((val), drvdata->base + off)
+#define etb_readl(drvdata, off)		__raw_readl(drvdata->base + off)
+
+#define ETB_RAM_DEPTH_REG	(0x004)
+#define ETB_STATUS_REG		(0x00C)
+#define ETB_RAM_READ_DATA_REG	(0x010)
+#define ETB_RAM_READ_POINTER	(0x014)
+#define ETB_RAM_WRITE_POINTER	(0x018)
+#define ETB_TRG			(0x01C)
+#define ETB_CTL_REG		(0x020)
+#define ETB_RWD_REG		(0x024)
+#define ETB_FFSR		(0x300)
+#define ETB_FFCR		(0x304)
+#define ETB_ITMISCOP0		(0xEE0)
+#define ETB_ITTRFLINACK		(0xEE4)
+#define ETB_ITTRFLIN		(0xEE8)
+#define ETB_ITATBDATA0		(0xEEC)
+#define ETB_ITATBCTR2		(0xEF0)
+#define ETB_ITATBCTR1		(0xEF4)
+#define ETB_ITATBCTR0		(0xEF8)
+
+
+#define BYTES_PER_WORD		4
+#define ETB_SIZE_WORDS		4096
+#define FRAME_SIZE_WORDS	4
+
+#define ETB_LOCK()							\
+do {									\
+	mb();								\
+	etb_writel(drvdata, 0x0, CORESIGHT_LAR);			\
+} while (0)
+#define ETB_UNLOCK()							\
+do {									\
+	etb_writel(drvdata, CORESIGHT_UNLOCK, CORESIGHT_LAR);		\
+	mb();								\
+} while (0)
+
+struct etb_drvdata {
+	uint8_t		*buf;
+	void __iomem	*base;
+	bool		enabled;
+	bool		reading;
+	spinlock_t	spinlock;
+	atomic_t	in_use;
+	struct device	*dev;
+	struct kobject	*kobj;
+	struct clk	*clk;
+	uint32_t	trigger_cntr;
+};
+
+static struct etb_drvdata *drvdata;
+
+static void __etb_enable(void)
+{
+	int i;
+
+	ETB_UNLOCK();
+
+	etb_writel(drvdata, 0x0, ETB_RAM_WRITE_POINTER);
+	for (i = 0; i < ETB_SIZE_WORDS; i++)
+		etb_writel(drvdata, 0x0, ETB_RWD_REG);
+
+	etb_writel(drvdata, 0x0, ETB_RAM_WRITE_POINTER);
+	etb_writel(drvdata, 0x0, ETB_RAM_READ_POINTER);
+
+	etb_writel(drvdata, drvdata->trigger_cntr, ETB_TRG);
+	etb_writel(drvdata, BIT(13) | BIT(0), ETB_FFCR);
+	etb_writel(drvdata, BIT(0), ETB_CTL_REG);
+
+	ETB_LOCK();
+}
+
+int etb_enable(void)
+{
+	int ret;
+	unsigned long flags;
+
+	ret = clk_prepare_enable(drvdata->clk);
+	if (ret)
+		return ret;
+
+	spin_lock_irqsave(&drvdata->spinlock, flags);
+	__etb_enable();
+	drvdata->enabled = true;
+	dev_info(drvdata->dev, "ETB enabled\n");
+	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+
+	return 0;
+}
+
+static void __etb_disable(void)
+{
+	int count;
+	uint32_t ffcr;
+
+	ETB_UNLOCK();
+
+	ffcr = etb_readl(drvdata, ETB_FFCR);
+	ffcr |= (BIT(12) | BIT(6));
+	etb_writel(drvdata, ffcr, ETB_FFCR);
+
+	for (count = TIMEOUT_US; BVAL(etb_readl(drvdata, ETB_FFCR), 6) != 0
+				&& count > 0; count--)
+		udelay(1);
+	WARN(count == 0, "timeout while flushing DRVDATA, ETB_FFCR: %#x\n",
+	     etb_readl(drvdata, ETB_FFCR));
+
+	etb_writel(drvdata, 0x0, ETB_CTL_REG);
+
+	for (count = TIMEOUT_US; BVAL(etb_readl(drvdata, ETB_FFSR), 1) != 1
+				&& count > 0; count--)
+		udelay(1);
+	WARN(count == 0, "timeout while disabling DRVDATA, ETB_FFSR: %#x\n",
+	     etb_readl(drvdata, ETB_FFSR));
+
+	ETB_LOCK();
+}
+
+void etb_disable(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&drvdata->spinlock, flags);
+	__etb_disable();
+	drvdata->enabled = false;
+	dev_info(drvdata->dev, "ETB disabled\n");
+	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+
+	clk_disable_unprepare(drvdata->clk);
+}
+
+static void __etb_dump(void)
+{
+	int i;
+	uint8_t *buf_ptr;
+	uint32_t read_data;
+	uint32_t read_ptr;
+	uint32_t write_ptr;
+	uint32_t frame_off;
+	uint32_t frame_endoff;
+
+	ETB_UNLOCK();
+
+	read_ptr = etb_readl(drvdata, ETB_RAM_READ_POINTER);
+	write_ptr = etb_readl(drvdata, ETB_RAM_WRITE_POINTER);
+
+	frame_off = write_ptr % FRAME_SIZE_WORDS;
+	frame_endoff = FRAME_SIZE_WORDS - frame_off;
+	if (frame_off) {
+		dev_err(drvdata->dev, "write_ptr: %lu not aligned to formatter "
+				"frame size\n", (unsigned long)write_ptr);
+		dev_err(drvdata->dev, "frameoff: %lu, frame_endoff: %lu\n",
+			(unsigned long)frame_off, (unsigned long)frame_endoff);
+		write_ptr += frame_endoff;
+	}
+
+	if ((etb_readl(drvdata, ETB_STATUS_REG) & BIT(0)) == 0)
+		etb_writel(drvdata, 0x0, ETB_RAM_READ_POINTER);
+	else
+		etb_writel(drvdata, write_ptr, ETB_RAM_READ_POINTER);
+
+	buf_ptr = drvdata->buf;
+	for (i = 0; i < ETB_SIZE_WORDS; i++) {
+		read_data = etb_readl(drvdata, ETB_RAM_READ_DATA_REG);
+		*buf_ptr++ = read_data >> 0;
+		*buf_ptr++ = read_data >> 8;
+		*buf_ptr++ = read_data >> 16;
+		*buf_ptr++ = read_data >> 24;
+	}
+
+	if (frame_off) {
+		buf_ptr -= (frame_endoff * BYTES_PER_WORD);
+		for (i = 0; i < frame_endoff; i++) {
+			*buf_ptr++ = 0x0;
+			*buf_ptr++ = 0x0;
+			*buf_ptr++ = 0x0;
+			*buf_ptr++ = 0x0;
+		}
+	}
+
+	etb_writel(drvdata, read_ptr, ETB_RAM_READ_POINTER);
+
+	ETB_LOCK();
+}
+
+void etb_dump(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&drvdata->spinlock, flags);
+	if (drvdata->enabled) {
+		__etb_disable();
+		__etb_dump();
+		__etb_enable();
+
+		dev_info(drvdata->dev, "ETB dumped\n");
+	}
+	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+}
+
+static int etb_open(struct inode *inode, struct file *file)
+{
+	if (atomic_cmpxchg(&drvdata->in_use, 0, 1))
+		return -EBUSY;
+
+	dev_dbg(drvdata->dev, "%s: successfully opened\n", __func__);
+	return 0;
+}
+
+static ssize_t etb_read(struct file *file, char __user *data,
+				size_t len, loff_t *ppos)
+{
+	if (drvdata->reading == false) {
+		etb_dump();
+		drvdata->reading = true;
+	}
+
+	if (*ppos + len > ETB_SIZE_WORDS * BYTES_PER_WORD)
+		len = ETB_SIZE_WORDS * BYTES_PER_WORD - *ppos;
+
+	if (copy_to_user(data, drvdata->buf + *ppos, len)) {
+		dev_dbg(drvdata->dev, "%s: copy_to_user failed\n", __func__);
+		return -EFAULT;
+	}
+
+	*ppos += len;
+
+	dev_dbg(drvdata->dev, "%s: %d bytes copied, %d bytes left\n",
+		__func__, len, (int) (ETB_SIZE_WORDS * BYTES_PER_WORD - *ppos));
+
+	return len;
+}
+
+static int etb_release(struct inode *inode, struct file *file)
+{
+	drvdata->reading = false;
+
+	atomic_set(&drvdata->in_use, 0);
+
+	dev_dbg(drvdata->dev, "%s: released\n", __func__);
+
+	return 0;
+}
+
+static const struct file_operations etb_fops = {
+	.owner =	THIS_MODULE,
+	.open =		etb_open,
+	.read =		etb_read,
+	.release =	etb_release,
+};
+
+static struct miscdevice etb_misc = {
+	.name =		"msm_etb",
+	.minor =	MISC_DYNAMIC_MINOR,
+	.fops =		&etb_fops,
+};
+
+static ssize_t etb_show_trigger_cntr(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	unsigned long val = drvdata->trigger_cntr;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etb_store_trigger_cntr(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t size)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	drvdata->trigger_cntr = val;
+	return size;
+}
+static DEVICE_ATTR(trigger_cntr, S_IRUGO | S_IWUSR, etb_show_trigger_cntr,
+		   etb_store_trigger_cntr);
+
+static int __devinit etb_sysfs_init(void)
+{
+	int ret;
+
+	drvdata->kobj = kobject_create_and_add("etb", qdss_get_modulekobj());
+	if (!drvdata->kobj) {
+		dev_err(drvdata->dev, "failed to create ETB sysfs kobject\n");
+		ret = -ENOMEM;
+		goto err_create;
+	}
+
+	ret = sysfs_create_file(drvdata->kobj, &dev_attr_trigger_cntr.attr);
+	if (ret) {
+		dev_err(drvdata->dev, "failed to create ETB sysfs trigger_cntr"
+		" attribute\n");
+		goto err_file;
+	}
+
+	return 0;
+err_file:
+	kobject_put(drvdata->kobj);
+err_create:
+	return ret;
+}
+
+static void __devexit etb_sysfs_exit(void)
+{
+	sysfs_remove_file(drvdata->kobj, &dev_attr_trigger_cntr.attr);
+	kobject_put(drvdata->kobj);
+}
+
+static int __devinit etb_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct resource *res;
+
+	drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata) {
+		ret = -ENOMEM;
+		goto err_kzalloc_drvdata;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		ret = -EINVAL;
+		goto err_res;
+	}
+
+	drvdata->base = ioremap_nocache(res->start, resource_size(res));
+	if (!drvdata->base) {
+		ret = -EINVAL;
+		goto err_ioremap;
+	}
+
+	drvdata->dev = &pdev->dev;
+
+	spin_lock_init(&drvdata->spinlock);
+
+	drvdata->clk = clk_get(drvdata->dev, "core_clk");
+	if (IS_ERR(drvdata->clk)) {
+		ret = PTR_ERR(drvdata->clk);
+		goto err_clk_get;
+	}
+
+	ret = clk_set_rate(drvdata->clk, CORESIGHT_CLK_RATE_TRACE);
+	if (ret)
+		goto err_clk_rate;
+
+	ret = misc_register(&etb_misc);
+	if (ret)
+		goto err_misc;
+
+	drvdata->buf = kzalloc(ETB_SIZE_WORDS * BYTES_PER_WORD, GFP_KERNEL);
+	if (!drvdata->buf) {
+		ret = -ENOMEM;
+		goto err_alloc;
+	}
+
+	etb_sysfs_init();
+
+	dev_info(drvdata->dev, "ETB initialized\n");
+	return 0;
+
+err_alloc:
+	misc_deregister(&etb_misc);
+err_misc:
+err_clk_rate:
+	clk_put(drvdata->clk);
+err_clk_get:
+	iounmap(drvdata->base);
+err_ioremap:
+err_res:
+	kfree(drvdata);
+err_kzalloc_drvdata:
+	dev_err(drvdata->dev, "ETB init failed\n");
+	return ret;
+}
+
+static int __devexit etb_remove(struct platform_device *pdev)
+{
+	if (drvdata->enabled)
+		etb_disable();
+	etb_sysfs_exit();
+	kfree(drvdata->buf);
+	misc_deregister(&etb_misc);
+	clk_put(drvdata->clk);
+	iounmap(drvdata->base);
+	kfree(drvdata);
+
+	return 0;
+}
+
+static struct of_device_id etb_match[] = {
+	{.compatible = "qcom,msm-etb"},
+	{}
+};
+
+static struct platform_driver etb_driver = {
+	.probe          = etb_probe,
+	.remove         = __devexit_p(etb_remove),
+	.driver         = {
+		.name   = "msm_etb",
+		.owner	= THIS_MODULE,
+		.of_match_table = etb_match,
+	},
+};
+
+static int __init etb_init(void)
+{
+	return platform_driver_register(&etb_driver);
+}
+module_init(etb_init);
+
+static void __exit etb_exit(void)
+{
+	platform_driver_unregister(&etb_driver);
+}
+module_exit(etb_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("CoreSight Embedded Trace Buffer driver");
diff --git a/drivers/coresight/coresight-etm.c b/drivers/coresight/coresight-etm.c
new file mode 100644
index 0000000..b3d2a16
--- /dev/null
+++ b/drivers/coresight/coresight-etm.c
@@ -0,0 +1,1646 @@
+/* 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
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/smp.h>
+#include <linux/wakelock.h>
+#include <linux/pm_qos.h>
+#include <linux/sysfs.h>
+#include <linux/stat.h>
+#include <linux/clk.h>
+#include <linux/coresight.h>
+#include <asm/sections.h>
+#include <mach/socinfo.h>
+
+#include "coresight-priv.h"
+
+#define etm_writel(drvdata, cpu, val, off)	\
+			__raw_writel((val), drvdata->base + (SZ_4K * cpu) + off)
+#define etm_readl(drvdata, cpu, off)	\
+			__raw_readl(drvdata->base + (SZ_4K * cpu) + off)
+
+/*
+ * Device registers:
+ * 0x000 - 0x2FC: Trace		registers
+ * 0x300 - 0x314: Management	registers
+ * 0x318 - 0xEFC: Trace		registers
+ *
+ * Coresight registers
+ * 0xF00 - 0xF9C: Management	registers
+ * 0xFA0 - 0xFA4: Management	registers in PFTv1.0
+ *		  Trace		registers in PFTv1.1
+ * 0xFA8 - 0xFFC: Management	registers
+ */
+
+/* Trace registers (0x000-0x2FC) */
+#define ETMCR			(0x000)
+#define ETMCCR			(0x004)
+#define ETMTRIGGER		(0x008)
+#define ETMSR			(0x010)
+#define ETMSCR			(0x014)
+#define ETMTSSCR		(0x018)
+#define ETMTEEVR		(0x020)
+#define ETMTECR1		(0x024)
+#define ETMFFLR			(0x02C)
+#define ETMACVRn(n)		(0x040 + (n * 4))
+#define ETMACTRn(n)		(0x080 + (n * 4))
+#define ETMCNTRLDVRn(n)		(0x140 + (n * 4))
+#define ETMCNTENRn(n)		(0x150 + (n * 4))
+#define ETMCNTRLDEVRn(n)	(0x160 + (n * 4))
+#define ETMCNTVRn(n)		(0x170 + (n * 4))
+#define ETMSQ12EVR		(0x180)
+#define ETMSQ21EVR		(0x184)
+#define ETMSQ23EVR		(0x188)
+#define ETMSQ31EVR		(0x18C)
+#define ETMSQ32EVR		(0x190)
+#define ETMSQ13EVR		(0x194)
+#define ETMSQR			(0x19C)
+#define ETMEXTOUTEVRn(n)	(0x1A0 + (n * 4))
+#define ETMCIDCVRn(n)		(0x1B0 + (n * 4))
+#define ETMCIDCMR		(0x1BC)
+#define ETMIMPSPEC0		(0x1C0)
+#define ETMIMPSPEC1		(0x1C4)
+#define ETMIMPSPEC2		(0x1C8)
+#define ETMIMPSPEC3		(0x1CC)
+#define ETMIMPSPEC4		(0x1D0)
+#define ETMIMPSPEC5		(0x1D4)
+#define ETMIMPSPEC6		(0x1D8)
+#define ETMIMPSPEC7		(0x1DC)
+#define ETMSYNCFR		(0x1E0)
+#define ETMIDR			(0x1E4)
+#define ETMCCER			(0x1E8)
+#define ETMEXTINSELR		(0x1EC)
+#define ETMTESSEICR		(0x1F0)
+#define ETMEIBCR		(0x1F4)
+#define ETMTSEVR		(0x1F8)
+#define ETMAUXCR		(0x1FC)
+#define ETMTRACEIDR		(0x200)
+#define ETMVMIDCVR		(0x240)
+/* Management registers (0x300-0x314) */
+#define ETMOSLAR		(0x300)
+#define ETMOSLSR		(0x304)
+#define ETMOSSRR		(0x308)
+#define ETMPDCR			(0x310)
+#define ETMPDSR			(0x314)
+
+#define ETM_MAX_ADDR_CMP	(16)
+#define ETM_MAX_CNTR		(4)
+#define ETM_MAX_CTXID_CMP	(3)
+
+#define ETM_MODE_EXCLUDE	BIT(0)
+#define ETM_MODE_CYCACC		BIT(1)
+#define ETM_MODE_STALL		BIT(2)
+#define ETM_MODE_TIMESTAMP	BIT(3)
+#define ETM_MODE_CTXID		BIT(4)
+#define ETM_MODE_ALL		(0x1F)
+
+#define ETM_EVENT_MASK		(0x1FFFF)
+#define ETM_SYNC_MASK		(0xFFF)
+#define ETM_ALL_MASK		(0xFFFFFFFF)
+
+#define ETM_SEQ_STATE_MAX_VAL	(0x2)
+
+enum {
+	ETM_ADDR_TYPE_NONE,
+	ETM_ADDR_TYPE_SINGLE,
+	ETM_ADDR_TYPE_RANGE,
+	ETM_ADDR_TYPE_START,
+	ETM_ADDR_TYPE_STOP,
+};
+
+#define ETM_LOCK(cpu)							\
+do {									\
+	mb();								\
+	etm_writel(drvdata, cpu, 0x0, CORESIGHT_LAR);			\
+} while (0)
+#define ETM_UNLOCK(cpu)							\
+do {									\
+	etm_writel(drvdata, cpu, CORESIGHT_UNLOCK, CORESIGHT_LAR);	\
+	mb();								\
+} while (0)
+
+
+#ifdef MODULE_PARAM_PREFIX
+#undef MODULE_PARAM_PREFIX
+#endif
+#define MODULE_PARAM_PREFIX "coresight."
+
+#ifdef CONFIG_MSM_QDSS_ETM_DEFAULT_ENABLE
+static int etm_boot_enable = 1;
+#else
+static int etm_boot_enable;
+#endif
+module_param_named(
+	etm_boot_enable, etm_boot_enable, int, S_IRUGO
+);
+
+struct etm_drvdata {
+	void __iomem			*base;
+	bool				enabled;
+	struct wake_lock		wake_lock;
+	struct pm_qos_request		qos_req;
+	struct qdss_source		*src;
+	struct mutex			mutex;
+	struct device			*dev;
+	struct kobject			*kobj;
+	struct clk			*clk;
+	uint8_t				arch;
+	uint8_t				nr_addr_cmp;
+	uint8_t				nr_cntr;
+	uint8_t				nr_ext_inp;
+	uint8_t				nr_ext_out;
+	uint8_t				nr_ctxid_cmp;
+	uint8_t				reset;
+	uint32_t			mode;
+	uint32_t			ctrl;
+	uint32_t			trigger_event;
+	uint32_t			startstop_ctrl;
+	uint32_t			enable_event;
+	uint32_t			enable_ctrl1;
+	uint32_t			fifofull_level;
+	uint8_t				addr_idx;
+	uint32_t			addr_val[ETM_MAX_ADDR_CMP];
+	uint32_t			addr_acctype[ETM_MAX_ADDR_CMP];
+	uint32_t			addr_type[ETM_MAX_ADDR_CMP];
+	uint8_t				cntr_idx;
+	uint32_t			cntr_rld_val[ETM_MAX_CNTR];
+	uint32_t			cntr_event[ETM_MAX_CNTR];
+	uint32_t			cntr_rld_event[ETM_MAX_CNTR];
+	uint32_t			cntr_val[ETM_MAX_CNTR];
+	uint32_t			seq_12_event;
+	uint32_t			seq_21_event;
+	uint32_t			seq_23_event;
+	uint32_t			seq_31_event;
+	uint32_t			seq_32_event;
+	uint32_t			seq_13_event;
+	uint32_t			seq_curr_state;
+	uint8_t				ctxid_idx;
+	uint32_t			ctxid_val[ETM_MAX_CTXID_CMP];
+	uint32_t			ctxid_mask;
+	uint32_t			sync_freq;
+	uint32_t			timestamp_event;
+};
+
+static struct etm_drvdata *drvdata;
+
+
+/* ETM clock is derived from the processor clock and gets enabled on a
+ * logical OR of below items on Krait (pass2 onwards):
+ * 1.CPMR[ETMCLKEN] is 1
+ * 2.ETMCR[PD] is 0
+ * 3.ETMPDCR[PU] is 1
+ * 4.Reset is asserted (core or debug)
+ * 5.APB memory mapped requests (eg. EDAP access)
+ *
+ * 1., 2. and 3. above are permanent enables whereas 4. and 5. are temporary
+ * enables
+ *
+ * We rely on 5. to be able to access ETMCR and then use 2. above for ETM
+ * clock vote in the driver and the save-restore code uses 1. above
+ * for its vote
+ */
+static void etm_set_pwrdwn(int cpu)
+{
+	uint32_t etmcr;
+
+	etmcr = etm_readl(drvdata, cpu, ETMCR);
+	etmcr |= BIT(0);
+	etm_writel(drvdata, cpu, etmcr, ETMCR);
+}
+
+static void etm_clr_pwrdwn(int cpu)
+{
+	uint32_t etmcr;
+
+	etmcr = etm_readl(drvdata, cpu, ETMCR);
+	etmcr &= ~BIT(0);
+	etm_writel(drvdata, cpu, etmcr, ETMCR);
+}
+
+static void etm_set_prog(int cpu)
+{
+	uint32_t etmcr;
+	int count;
+
+	etmcr = etm_readl(drvdata, cpu, ETMCR);
+	etmcr |= BIT(10);
+	etm_writel(drvdata, cpu, etmcr, ETMCR);
+
+	for (count = TIMEOUT_US; BVAL(etm_readl(drvdata, cpu, ETMSR), 1) != 1
+				&& count > 0; count--)
+		udelay(1);
+	WARN(count == 0, "timeout while setting prog bit, ETMSR: %#x\n",
+	     etm_readl(drvdata, cpu, ETMSR));
+}
+
+static void etm_clr_prog(int cpu)
+{
+	uint32_t etmcr;
+	int count;
+
+	etmcr = etm_readl(drvdata, cpu, ETMCR);
+	etmcr &= ~BIT(10);
+	etm_writel(drvdata, cpu, etmcr, ETMCR);
+
+	for (count = TIMEOUT_US; BVAL(etm_readl(drvdata, cpu, ETMSR), 1) != 0
+				&& count > 0; count--)
+		udelay(1);
+	WARN(count == 0, "timeout while clearing prog bit, ETMSR: %#x\n",
+	     etm_readl(drvdata, cpu, ETMSR));
+}
+
+static void __etm_enable(int cpu)
+{
+	int i;
+
+	ETM_UNLOCK(cpu);
+	/* Vote for ETM power/clock enable */
+	etm_clr_pwrdwn(cpu);
+	etm_set_prog(cpu);
+
+	etm_writel(drvdata, cpu, drvdata->ctrl | BIT(10), ETMCR);
+	etm_writel(drvdata, cpu, drvdata->trigger_event, ETMTRIGGER);
+	etm_writel(drvdata, cpu, drvdata->startstop_ctrl, ETMTSSCR);
+	etm_writel(drvdata, cpu, drvdata->enable_event, ETMTEEVR);
+	etm_writel(drvdata, cpu, drvdata->enable_ctrl1, ETMTECR1);
+	etm_writel(drvdata, cpu, drvdata->fifofull_level, ETMFFLR);
+	for (i = 0; i < drvdata->nr_addr_cmp; i++) {
+		etm_writel(drvdata, cpu, drvdata->addr_val[i], ETMACVRn(i));
+		etm_writel(drvdata, cpu, drvdata->addr_acctype[i], ETMACTRn(i));
+	}
+	for (i = 0; i < drvdata->nr_cntr; i++) {
+		etm_writel(drvdata, cpu, drvdata->cntr_rld_val[i],
+			   ETMCNTRLDVRn(i));
+		etm_writel(drvdata, cpu, drvdata->cntr_event[i], ETMCNTENRn(i));
+		etm_writel(drvdata, cpu, drvdata->cntr_rld_event[i],
+			   ETMCNTRLDEVRn(i));
+		etm_writel(drvdata, cpu, drvdata->cntr_val[i], ETMCNTVRn(i));
+	}
+	etm_writel(drvdata, cpu, drvdata->seq_12_event, ETMSQ12EVR);
+	etm_writel(drvdata, cpu, drvdata->seq_21_event, ETMSQ21EVR);
+	etm_writel(drvdata, cpu, drvdata->seq_23_event, ETMSQ23EVR);
+	etm_writel(drvdata, cpu, drvdata->seq_31_event, ETMSQ31EVR);
+	etm_writel(drvdata, cpu, drvdata->seq_32_event, ETMSQ32EVR);
+	etm_writel(drvdata, cpu, drvdata->seq_13_event, ETMSQ13EVR);
+	etm_writel(drvdata, cpu, drvdata->seq_curr_state, ETMSQR);
+	for (i = 0; i < drvdata->nr_ext_out; i++)
+		etm_writel(drvdata, cpu, 0x0000406F, ETMEXTOUTEVRn(i));
+	for (i = 0; i < drvdata->nr_ctxid_cmp; i++)
+		etm_writel(drvdata, cpu, drvdata->ctxid_val[i], ETMCIDCVRn(i));
+	etm_writel(drvdata, cpu, drvdata->ctxid_mask, ETMCIDCMR);
+	etm_writel(drvdata, cpu, drvdata->sync_freq, ETMSYNCFR);
+	etm_writel(drvdata, cpu, 0x00000000, ETMEXTINSELR);
+	etm_writel(drvdata, cpu, drvdata->timestamp_event, ETMTSEVR);
+	etm_writel(drvdata, cpu, 0x00000000, ETMAUXCR);
+	etm_writel(drvdata, cpu, cpu+1, ETMTRACEIDR);
+	etm_writel(drvdata, cpu, 0x00000000, ETMVMIDCVR);
+
+	etm_clr_prog(cpu);
+	ETM_LOCK(cpu);
+}
+
+static int etm_enable(void)
+{
+	int ret, cpu;
+
+	if (drvdata->enabled) {
+		dev_err(drvdata->dev, "ETM tracing already enabled\n");
+		ret = -EPERM;
+		goto err;
+	}
+
+	wake_lock(&drvdata->wake_lock);
+	/* 1. causes all online cpus to come out of idle PC
+	 * 2. prevents idle PC until save restore flag is enabled atomically
+	 *
+	 * we rely on the user to prevent hotplug on/off racing with this
+	 * operation and to ensure cores where trace is expected to be turned
+	 * on are already hotplugged on
+	 */
+	pm_qos_update_request(&drvdata->qos_req, 0);
+
+	ret = clk_prepare_enable(drvdata->clk);
+	if (ret)
+		goto err_clk;
+
+	ret = qdss_enable(drvdata->src);
+	if (ret)
+		goto err_qdss;
+
+	for_each_online_cpu(cpu)
+		__etm_enable(cpu);
+
+	drvdata->enabled = true;
+
+	pm_qos_update_request(&drvdata->qos_req, PM_QOS_DEFAULT_VALUE);
+	wake_unlock(&drvdata->wake_lock);
+
+	dev_info(drvdata->dev, "ETM tracing enabled\n");
+	return 0;
+
+err_qdss:
+	clk_disable_unprepare(drvdata->clk);
+err_clk:
+	pm_qos_update_request(&drvdata->qos_req, PM_QOS_DEFAULT_VALUE);
+	wake_unlock(&drvdata->wake_lock);
+err:
+	return ret;
+}
+
+static void __etm_disable(int cpu)
+{
+	ETM_UNLOCK(cpu);
+	etm_set_prog(cpu);
+
+	/* program trace enable to low by using always false event */
+	etm_writel(drvdata, cpu, 0x6F | BIT(14), ETMTEEVR);
+
+	/* Vote for ETM power/clock disable */
+	etm_set_pwrdwn(cpu);
+	ETM_LOCK(cpu);
+}
+
+static int etm_disable(void)
+{
+	int ret, cpu;
+
+	if (!drvdata->enabled) {
+		dev_err(drvdata->dev, "ETM tracing already disabled\n");
+		ret = -EPERM;
+		goto err;
+	}
+
+	wake_lock(&drvdata->wake_lock);
+	/* 1. causes all online cpus to come out of idle PC
+	 * 2. prevents idle PC until save restore flag is disabled atomically
+	 *
+	 * we rely on the user to prevent hotplug on/off racing with this
+	 * operation and to ensure cores where trace is expected to be turned
+	 * off are already hotplugged on
+	 */
+	pm_qos_update_request(&drvdata->qos_req, 0);
+
+	for_each_online_cpu(cpu)
+		__etm_disable(cpu);
+
+	drvdata->enabled = false;
+
+	qdss_disable(drvdata->src);
+
+	clk_disable_unprepare(drvdata->clk);
+
+	pm_qos_update_request(&drvdata->qos_req, PM_QOS_DEFAULT_VALUE);
+	wake_unlock(&drvdata->wake_lock);
+
+	dev_info(drvdata->dev, "ETM tracing disabled\n");
+	return 0;
+err:
+	return ret;
+}
+
+/* Memory mapped writes to clear os lock not supported */
+static void etm_os_unlock(void *unused)
+{
+	unsigned long value = 0x0;
+
+	asm("mcr p14, 1, %0, c1, c0, 4\n\t" : : "r" (value));
+	asm("isb\n\t");
+}
+
+static ssize_t etm_show_enabled(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	unsigned long val = drvdata->enabled;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_enabled(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf, size_t size)
+{
+	int ret = 0;
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	mutex_lock(&drvdata->mutex);
+	if (val)
+		ret = etm_enable();
+	else
+		ret = etm_disable();
+	mutex_unlock(&drvdata->mutex);
+
+	if (ret)
+		return ret;
+	return size;
+}
+static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, etm_show_enabled,
+		   etm_store_enabled);
+
+static ssize_t etm_show_nr_addr_cmp(struct device *dev,
+				    struct device_attribute *attr, char *buf)
+{
+	unsigned long val = drvdata->nr_addr_cmp;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+static DEVICE_ATTR(nr_addr_cmp, S_IRUGO, etm_show_nr_addr_cmp, NULL);
+
+static ssize_t etm_show_nr_cntr(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	unsigned long val = drvdata->nr_cntr;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+static DEVICE_ATTR(nr_cntr, S_IRUGO, etm_show_nr_cntr, NULL);
+
+static ssize_t etm_show_nr_ctxid_cmp(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	unsigned long val = drvdata->nr_ctxid_cmp;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+static DEVICE_ATTR(nr_ctxid_cmp, S_IRUGO, etm_show_nr_ctxid_cmp, NULL);
+
+static ssize_t etm_show_reset(struct device *dev, struct device_attribute *attr,
+			      char *buf)
+{
+	unsigned long val = drvdata->reset;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+/* Reset to trace everything i.e. exclude nothing. */
+static ssize_t etm_store_reset(struct device *dev,
+			       struct device_attribute *attr, const char *buf,
+			       size_t size)
+{
+	int i;
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	mutex_lock(&drvdata->mutex);
+	if (val) {
+		drvdata->mode = ETM_MODE_EXCLUDE;
+		drvdata->ctrl = 0x0;
+		if (cpu_is_krait_v1()) {
+			drvdata->mode |= ETM_MODE_CYCACC;
+			drvdata->ctrl |= BIT(12);
+		}
+		drvdata->trigger_event = 0x406F;
+		drvdata->startstop_ctrl = 0x0;
+		drvdata->enable_event = 0x6F;
+		drvdata->enable_ctrl1 = 0x1000000;
+		drvdata->fifofull_level = 0x28;
+		drvdata->addr_idx = 0x0;
+		for (i = 0; i < drvdata->nr_addr_cmp; i++) {
+			drvdata->addr_val[i] = 0x0;
+			drvdata->addr_acctype[i] = 0x0;
+			drvdata->addr_type[i] = ETM_ADDR_TYPE_NONE;
+		}
+		drvdata->cntr_idx = 0x0;
+		for (i = 0; i < drvdata->nr_cntr; i++) {
+			drvdata->cntr_rld_val[i] = 0x0;
+			drvdata->cntr_event[i] = 0x406F;
+			drvdata->cntr_rld_event[i] = 0x406F;
+			drvdata->cntr_val[i] = 0x0;
+		}
+		drvdata->seq_12_event = 0x406F;
+		drvdata->seq_21_event = 0x406F;
+		drvdata->seq_23_event = 0x406F;
+		drvdata->seq_31_event = 0x406F;
+		drvdata->seq_32_event = 0x406F;
+		drvdata->seq_13_event = 0x406F;
+		drvdata->seq_curr_state = 0x0;
+		drvdata->ctxid_idx = 0x0;
+		for (i = 0; i < drvdata->nr_ctxid_cmp; i++)
+			drvdata->ctxid_val[i] = 0x0;
+		drvdata->ctxid_mask = 0x0;
+		drvdata->sync_freq = 0x80;
+		drvdata->timestamp_event = 0x406F;
+	}
+	mutex_unlock(&drvdata->mutex);
+	return size;
+}
+static DEVICE_ATTR(reset, S_IRUGO | S_IWUSR, etm_show_reset, etm_store_reset);
+
+static ssize_t etm_show_mode(struct device *dev, struct device_attribute *attr,
+			      char *buf)
+{
+	unsigned long val = drvdata->mode;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_mode(struct device *dev, struct device_attribute *attr,
+			      const char *buf, size_t size)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	mutex_lock(&drvdata->mutex);
+	drvdata->mode = val & ETM_MODE_ALL;
+
+	if (drvdata->mode & ETM_MODE_EXCLUDE)
+		drvdata->enable_ctrl1 |= BIT(24);
+	else
+		drvdata->enable_ctrl1 &= ~BIT(24);
+
+	if (drvdata->mode & ETM_MODE_CYCACC)
+		drvdata->ctrl |= BIT(12);
+	else
+		drvdata->ctrl &= ~BIT(12);
+
+	if (drvdata->mode & ETM_MODE_STALL)
+		drvdata->ctrl |= BIT(7);
+	else
+		drvdata->ctrl &= ~BIT(7);
+
+	if (drvdata->mode & ETM_MODE_TIMESTAMP)
+		drvdata->ctrl |= BIT(28);
+	else
+		drvdata->ctrl &= ~BIT(28);
+	if (drvdata->mode & ETM_MODE_CTXID)
+		drvdata->ctrl |= (BIT(14) | BIT(15));
+	else
+		drvdata->ctrl &= ~(BIT(14) | BIT(15));
+	mutex_unlock(&drvdata->mutex);
+
+	return size;
+}
+static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, etm_show_mode, etm_store_mode);
+
+static ssize_t etm_show_trigger_event(struct device *dev,
+				      struct device_attribute *attr, char *buf)
+{
+	unsigned long val = drvdata->trigger_event;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_trigger_event(struct device *dev,
+				       struct device_attribute *attr,
+				       const char *buf, size_t size)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	drvdata->trigger_event = val & ETM_EVENT_MASK;
+	return size;
+}
+static DEVICE_ATTR(trigger_event, S_IRUGO | S_IWUSR, etm_show_trigger_event,
+		   etm_store_trigger_event);
+
+static ssize_t etm_show_enable_event(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	unsigned long val = drvdata->enable_event;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_enable_event(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t size)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	drvdata->enable_event = val & ETM_EVENT_MASK;
+	return size;
+}
+static DEVICE_ATTR(enable_event, S_IRUGO | S_IWUSR, etm_show_enable_event,
+		   etm_store_enable_event);
+
+static ssize_t etm_show_fifofull_level(struct device *dev,
+				       struct device_attribute *attr, char *buf)
+{
+	unsigned long val = drvdata->fifofull_level;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_fifofull_level(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf, size_t size)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	drvdata->fifofull_level = val;
+	return size;
+}
+static DEVICE_ATTR(fifofull_level, S_IRUGO | S_IWUSR, etm_show_fifofull_level,
+		   etm_store_fifofull_level);
+
+static ssize_t etm_show_addr_idx(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	unsigned long val = drvdata->addr_idx;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_addr_idx(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf, size_t size)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+	if (val >= drvdata->nr_addr_cmp)
+		return -EINVAL;
+
+	/* Use mutex to ensure index doesn't change while it gets dereferenced
+	 * multiple times within a mutex block elsewhere.
+	 */
+	mutex_lock(&drvdata->mutex);
+	drvdata->addr_idx = val;
+	mutex_unlock(&drvdata->mutex);
+	return size;
+}
+static DEVICE_ATTR(addr_idx, S_IRUGO | S_IWUSR, etm_show_addr_idx,
+		   etm_store_addr_idx);
+
+static ssize_t etm_show_addr_single(struct device *dev,
+				    struct device_attribute *attr, char *buf)
+{
+	unsigned long val;
+	uint8_t idx;
+
+	mutex_lock(&drvdata->mutex);
+	idx = drvdata->addr_idx;
+	if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+	      drvdata->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
+		mutex_unlock(&drvdata->mutex);
+		return -EPERM;
+	}
+
+	val = drvdata->addr_val[idx];
+	mutex_unlock(&drvdata->mutex);
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_addr_single(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t size)
+{
+	unsigned long val;
+	uint8_t idx;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	mutex_lock(&drvdata->mutex);
+	idx = drvdata->addr_idx;
+	if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+	      drvdata->addr_type[idx] == ETM_ADDR_TYPE_SINGLE)) {
+		mutex_unlock(&drvdata->mutex);
+		return -EPERM;
+	}
+
+	drvdata->addr_val[idx] = val;
+	drvdata->addr_type[idx] = ETM_ADDR_TYPE_SINGLE;
+	mutex_unlock(&drvdata->mutex);
+	return size;
+}
+static DEVICE_ATTR(addr_single, S_IRUGO | S_IWUSR, etm_show_addr_single,
+		   etm_store_addr_single);
+
+static ssize_t etm_show_addr_range(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	unsigned long val1, val2;
+	uint8_t idx;
+
+	mutex_lock(&drvdata->mutex);
+	idx = drvdata->addr_idx;
+	if (idx % 2 != 0) {
+		mutex_unlock(&drvdata->mutex);
+		return -EPERM;
+	}
+	if (!((drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE &&
+	       drvdata->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
+	      (drvdata->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
+	       drvdata->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
+		mutex_unlock(&drvdata->mutex);
+		return -EPERM;
+	}
+
+	val1 = drvdata->addr_val[idx];
+	val2 = drvdata->addr_val[idx + 1];
+	mutex_unlock(&drvdata->mutex);
+	return scnprintf(buf, PAGE_SIZE, "%#lx %#lx\n", val1, val2);
+}
+
+static ssize_t etm_store_addr_range(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t size)
+{
+	unsigned long val1, val2;
+	uint8_t idx;
+
+	if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
+		return -EINVAL;
+	/* lower address comparator cannot have a higher address value */
+	if (val1 > val2)
+		return -EINVAL;
+
+	mutex_lock(&drvdata->mutex);
+	idx = drvdata->addr_idx;
+	if (idx % 2 != 0) {
+		mutex_unlock(&drvdata->mutex);
+		return -EPERM;
+	}
+	if (!((drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE &&
+	       drvdata->addr_type[idx + 1] == ETM_ADDR_TYPE_NONE) ||
+	      (drvdata->addr_type[idx] == ETM_ADDR_TYPE_RANGE &&
+	       drvdata->addr_type[idx + 1] == ETM_ADDR_TYPE_RANGE))) {
+		mutex_unlock(&drvdata->mutex);
+		return -EPERM;
+	}
+
+	drvdata->addr_val[idx] = val1;
+	drvdata->addr_type[idx] = ETM_ADDR_TYPE_RANGE;
+	drvdata->addr_val[idx + 1] = val2;
+	drvdata->addr_type[idx + 1] = ETM_ADDR_TYPE_RANGE;
+	drvdata->enable_ctrl1 |= (1 << (idx/2));
+	mutex_unlock(&drvdata->mutex);
+	return size;
+}
+static DEVICE_ATTR(addr_range, S_IRUGO | S_IWUSR, etm_show_addr_range,
+		   etm_store_addr_range);
+
+static ssize_t etm_show_addr_start(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	unsigned long val;
+	uint8_t idx;
+
+	mutex_lock(&drvdata->mutex);
+	idx = drvdata->addr_idx;
+	if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+	      drvdata->addr_type[idx] == ETM_ADDR_TYPE_START)) {
+		mutex_unlock(&drvdata->mutex);
+		return -EPERM;
+	}
+
+	val = drvdata->addr_val[idx];
+	mutex_unlock(&drvdata->mutex);
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_addr_start(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t size)
+{
+	unsigned long val;
+	uint8_t idx;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	mutex_lock(&drvdata->mutex);
+	idx = drvdata->addr_idx;
+	if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+	      drvdata->addr_type[idx] == ETM_ADDR_TYPE_START)) {
+		mutex_unlock(&drvdata->mutex);
+		return -EPERM;
+	}
+
+	drvdata->addr_val[idx] = val;
+	drvdata->addr_type[idx] = ETM_ADDR_TYPE_START;
+	drvdata->startstop_ctrl |= (1 << idx);
+	drvdata->enable_ctrl1 |= BIT(25);
+	mutex_unlock(&drvdata->mutex);
+	return size;
+}
+static DEVICE_ATTR(addr_start, S_IRUGO | S_IWUSR, etm_show_addr_start,
+		   etm_store_addr_start);
+
+static ssize_t etm_show_addr_stop(struct device *dev,
+				  struct device_attribute *attr, char *buf)
+{
+	unsigned long val;
+	uint8_t idx;
+
+	mutex_lock(&drvdata->mutex);
+	idx = drvdata->addr_idx;
+	if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+	      drvdata->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
+		mutex_unlock(&drvdata->mutex);
+		return -EPERM;
+	}
+
+	val = drvdata->addr_val[idx];
+	mutex_unlock(&drvdata->mutex);
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_addr_stop(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf, size_t size)
+{
+	unsigned long val;
+	uint8_t idx;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	mutex_lock(&drvdata->mutex);
+	idx = drvdata->addr_idx;
+	if (!(drvdata->addr_type[idx] == ETM_ADDR_TYPE_NONE ||
+	      drvdata->addr_type[idx] == ETM_ADDR_TYPE_STOP)) {
+		mutex_unlock(&drvdata->mutex);
+		return -EPERM;
+	}
+
+	drvdata->addr_val[idx] = val;
+	drvdata->addr_type[idx] = ETM_ADDR_TYPE_STOP;
+	drvdata->startstop_ctrl |= (1 << (idx + 16));
+	drvdata->enable_ctrl1 |= BIT(25);
+	mutex_unlock(&drvdata->mutex);
+	return size;
+}
+static DEVICE_ATTR(addr_stop, S_IRUGO | S_IWUSR, etm_show_addr_stop,
+		   etm_store_addr_stop);
+
+static ssize_t etm_show_addr_acctype(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	unsigned long val;
+
+	mutex_lock(&drvdata->mutex);
+	val = drvdata->addr_acctype[drvdata->addr_idx];
+	mutex_unlock(&drvdata->mutex);
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_addr_acctype(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t size)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	mutex_lock(&drvdata->mutex);
+	drvdata->addr_acctype[drvdata->addr_idx] = val;
+	mutex_unlock(&drvdata->mutex);
+	return size;
+}
+static DEVICE_ATTR(addr_acctype, S_IRUGO | S_IWUSR, etm_show_addr_acctype,
+		   etm_store_addr_acctype);
+
+static ssize_t etm_show_cntr_idx(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	unsigned long val = drvdata->addr_idx;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_cntr_idx(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf, size_t size)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+	if (val >= drvdata->nr_cntr)
+		return -EINVAL;
+
+	/* Use mutex to ensure index doesn't change while it gets dereferenced
+	 * multiple times within a mutex block elsewhere.
+	 */
+	mutex_lock(&drvdata->mutex);
+	drvdata->cntr_idx = val;
+	mutex_unlock(&drvdata->mutex);
+	return size;
+}
+static DEVICE_ATTR(cntr_idx, S_IRUGO | S_IWUSR, etm_show_cntr_idx,
+		   etm_store_cntr_idx);
+
+static ssize_t etm_show_cntr_rld_val(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	unsigned long val;
+	mutex_lock(&drvdata->mutex);
+	val = drvdata->cntr_rld_val[drvdata->cntr_idx];
+	mutex_unlock(&drvdata->mutex);
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_cntr_rld_val(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t size)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	mutex_lock(&drvdata->mutex);
+	drvdata->cntr_rld_val[drvdata->cntr_idx] = val;
+	mutex_unlock(&drvdata->mutex);
+	return size;
+}
+static DEVICE_ATTR(cntr_rld_val, S_IRUGO | S_IWUSR, etm_show_cntr_rld_val,
+		   etm_store_cntr_rld_val);
+
+static ssize_t etm_show_cntr_event(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	unsigned long val;
+
+	mutex_lock(&drvdata->mutex);
+	val = drvdata->cntr_event[drvdata->cntr_idx];
+	mutex_unlock(&drvdata->mutex);
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_cntr_event(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t size)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	mutex_lock(&drvdata->mutex);
+	drvdata->cntr_event[drvdata->cntr_idx] = val & ETM_EVENT_MASK;
+	mutex_unlock(&drvdata->mutex);
+	return size;
+}
+static DEVICE_ATTR(cntr_event, S_IRUGO | S_IWUSR, etm_show_cntr_event,
+		   etm_store_cntr_event);
+
+static ssize_t etm_show_cntr_rld_event(struct device *dev,
+				       struct device_attribute *attr, char *buf)
+{
+	unsigned long val;
+
+	mutex_lock(&drvdata->mutex);
+	val = drvdata->cntr_rld_event[drvdata->cntr_idx];
+	mutex_unlock(&drvdata->mutex);
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_cntr_rld_event(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf, size_t size)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	mutex_lock(&drvdata->mutex);
+	drvdata->cntr_rld_event[drvdata->cntr_idx] = val & ETM_EVENT_MASK;
+	mutex_unlock(&drvdata->mutex);
+	return size;
+}
+static DEVICE_ATTR(cntr_rld_event, S_IRUGO | S_IWUSR, etm_show_cntr_rld_event,
+		   etm_store_cntr_rld_event);
+
+static ssize_t etm_show_cntr_val(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	unsigned long val;
+
+	mutex_lock(&drvdata->mutex);
+	val = drvdata->cntr_val[drvdata->cntr_idx];
+	mutex_unlock(&drvdata->mutex);
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_cntr_val(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf, size_t size)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	mutex_lock(&drvdata->mutex);
+	drvdata->cntr_val[drvdata->cntr_idx] = val;
+	mutex_unlock(&drvdata->mutex);
+	return size;
+}
+static DEVICE_ATTR(cntr_val, S_IRUGO | S_IWUSR, etm_show_cntr_val,
+		   etm_store_cntr_val);
+
+static ssize_t etm_show_seq_12_event(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	unsigned long val = drvdata->seq_12_event;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_seq_12_event(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t size)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	drvdata->seq_12_event = val & ETM_EVENT_MASK;
+	return size;
+}
+static DEVICE_ATTR(seq_12_event, S_IRUGO | S_IWUSR, etm_show_seq_12_event,
+		   etm_store_seq_12_event);
+
+static ssize_t etm_show_seq_21_event(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	unsigned long val = drvdata->seq_21_event;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_seq_21_event(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t size)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	drvdata->seq_21_event = val & ETM_EVENT_MASK;
+	return size;
+}
+static DEVICE_ATTR(seq_21_event, S_IRUGO | S_IWUSR, etm_show_seq_21_event,
+		   etm_store_seq_21_event);
+
+static ssize_t etm_show_seq_23_event(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	unsigned long val = drvdata->seq_23_event;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_seq_23_event(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t size)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	drvdata->seq_23_event = val & ETM_EVENT_MASK;
+	return size;
+}
+static DEVICE_ATTR(seq_23_event, S_IRUGO | S_IWUSR, etm_show_seq_23_event,
+		   etm_store_seq_23_event);
+
+static ssize_t etm_show_seq_31_event(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	unsigned long val = drvdata->seq_31_event;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_seq_31_event(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t size)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	drvdata->seq_31_event = val & ETM_EVENT_MASK;
+	return size;
+}
+static DEVICE_ATTR(seq_31_event, S_IRUGO | S_IWUSR, etm_show_seq_31_event,
+		   etm_store_seq_31_event);
+
+static ssize_t etm_show_seq_32_event(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	unsigned long val = drvdata->seq_32_event;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_seq_32_event(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t size)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	drvdata->seq_32_event = val & ETM_EVENT_MASK;
+	return size;
+}
+static DEVICE_ATTR(seq_32_event, S_IRUGO | S_IWUSR, etm_show_seq_32_event,
+		   etm_store_seq_32_event);
+
+static ssize_t etm_show_seq_13_event(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	unsigned long val = drvdata->seq_13_event;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_seq_13_event(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t size)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	drvdata->seq_13_event = val & ETM_EVENT_MASK;
+	return size;
+}
+static DEVICE_ATTR(seq_13_event, S_IRUGO | S_IWUSR, etm_show_seq_13_event,
+		   etm_store_seq_13_event);
+
+static ssize_t etm_show_seq_curr_state(struct device *dev,
+				       struct device_attribute *attr, char *buf)
+{
+	unsigned long val = drvdata->seq_curr_state;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_seq_curr_state(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf, size_t size)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+	if (val > ETM_SEQ_STATE_MAX_VAL)
+		return -EINVAL;
+
+	drvdata->seq_curr_state = val;
+	return size;
+}
+static DEVICE_ATTR(seq_curr_state, S_IRUGO | S_IWUSR, etm_show_seq_curr_state,
+		   etm_store_seq_curr_state);
+
+static ssize_t etm_show_ctxid_idx(struct device *dev,
+				  struct device_attribute *attr, char *buf)
+{
+	unsigned long val = drvdata->ctxid_idx;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_ctxid_idx(struct device *dev,
+				   struct device_attribute *attr,
+				   const char *buf, size_t size)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+	if (val >= drvdata->nr_ctxid_cmp)
+		return -EINVAL;
+
+	/* Use mutex to ensure index doesn't change while it gets dereferenced
+	 * multiple times within a mutex block elsewhere.
+	 */
+	mutex_lock(&drvdata->mutex);
+	drvdata->ctxid_idx = val;
+	mutex_unlock(&drvdata->mutex);
+	return size;
+}
+static DEVICE_ATTR(ctxid_idx, S_IRUGO | S_IWUSR, etm_show_ctxid_idx,
+		   etm_store_ctxid_idx);
+
+static ssize_t etm_show_ctxid_val(struct device *dev,
+				  struct device_attribute *attr, char *buf)
+{
+	unsigned long val;
+
+	mutex_lock(&drvdata->mutex);
+	val = drvdata->ctxid_val[drvdata->ctxid_idx];
+	mutex_unlock(&drvdata->mutex);
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_ctxid_val(struct device *dev,
+				   struct device_attribute *attr,
+				   const char *buf, size_t size)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	mutex_lock(&drvdata->mutex);
+	drvdata->ctxid_val[drvdata->ctxid_idx] = val;
+	mutex_unlock(&drvdata->mutex);
+	return size;
+}
+static DEVICE_ATTR(ctxid_val, S_IRUGO | S_IWUSR, etm_show_ctxid_val,
+		   etm_store_ctxid_val);
+
+static ssize_t etm_show_ctxid_mask(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	unsigned long val = drvdata->ctxid_mask;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_ctxid_mask(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t size)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	drvdata->ctxid_mask = val;
+	return size;
+}
+static DEVICE_ATTR(ctxid_mask, S_IRUGO | S_IWUSR, etm_show_ctxid_mask,
+		   etm_store_ctxid_mask);
+
+static ssize_t etm_show_sync_freq(struct device *dev,
+				  struct device_attribute *attr, char *buf)
+{
+	unsigned long val = drvdata->sync_freq;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_sync_freq(struct device *dev,
+				   struct device_attribute *attr,
+				   const char *buf, size_t size)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	drvdata->sync_freq = val & ETM_SYNC_MASK;
+	return size;
+}
+static DEVICE_ATTR(sync_freq, S_IRUGO | S_IWUSR, etm_show_sync_freq,
+		   etm_store_sync_freq);
+
+static ssize_t etm_show_timestamp_event(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	unsigned long val = drvdata->timestamp_event;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t etm_store_timestamp_event(struct device *dev,
+					 struct device_attribute *attr,
+					 const char *buf, size_t size)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	drvdata->timestamp_event = val & ETM_EVENT_MASK;
+	return size;
+}
+static DEVICE_ATTR(timestamp_event, S_IRUGO | S_IWUSR, etm_show_timestamp_event,
+		   etm_store_timestamp_event);
+
+static struct attribute *etm_attrs[] = {
+	&dev_attr_nr_addr_cmp.attr,
+	&dev_attr_nr_cntr.attr,
+	&dev_attr_nr_ctxid_cmp.attr,
+	&dev_attr_reset.attr,
+	&dev_attr_mode.attr,
+	&dev_attr_trigger_event.attr,
+	&dev_attr_enable_event.attr,
+	&dev_attr_fifofull_level.attr,
+	&dev_attr_addr_idx.attr,
+	&dev_attr_addr_single.attr,
+	&dev_attr_addr_range.attr,
+	&dev_attr_addr_start.attr,
+	&dev_attr_addr_stop.attr,
+	&dev_attr_addr_acctype.attr,
+	&dev_attr_cntr_idx.attr,
+	&dev_attr_cntr_rld_val.attr,
+	&dev_attr_cntr_event.attr,
+	&dev_attr_cntr_rld_event.attr,
+	&dev_attr_cntr_val.attr,
+	&dev_attr_seq_12_event.attr,
+	&dev_attr_seq_21_event.attr,
+	&dev_attr_seq_23_event.attr,
+	&dev_attr_seq_31_event.attr,
+	&dev_attr_seq_32_event.attr,
+	&dev_attr_seq_13_event.attr,
+	&dev_attr_seq_curr_state.attr,
+	&dev_attr_ctxid_idx.attr,
+	&dev_attr_ctxid_val.attr,
+	&dev_attr_ctxid_mask.attr,
+	&dev_attr_sync_freq.attr,
+	&dev_attr_timestamp_event.attr,
+	NULL,
+};
+
+static struct attribute_group etm_attr_grp = {
+	.attrs = etm_attrs,
+};
+
+static int __devinit etm_sysfs_init(void)
+{
+	int ret;
+
+	drvdata->kobj = kobject_create_and_add("etm", qdss_get_modulekobj());
+	if (!drvdata->kobj) {
+		dev_err(drvdata->dev, "failed to create ETM sysfs kobject\n");
+		ret = -ENOMEM;
+		goto err_create;
+	}
+
+	ret = sysfs_create_file(drvdata->kobj, &dev_attr_enabled.attr);
+	if (ret) {
+		dev_err(drvdata->dev, "failed to create ETM sysfs enabled"
+		" attribute\n");
+		goto err_file;
+	}
+
+	if (sysfs_create_group(drvdata->kobj, &etm_attr_grp))
+		dev_err(drvdata->dev, "failed to create ETM sysfs group\n");
+
+	return 0;
+err_file:
+	kobject_put(drvdata->kobj);
+err_create:
+	return ret;
+}
+
+static void __devexit etm_sysfs_exit(void)
+{
+	sysfs_remove_group(drvdata->kobj, &etm_attr_grp);
+	sysfs_remove_file(drvdata->kobj, &dev_attr_enabled.attr);
+	kobject_put(drvdata->kobj);
+}
+
+static bool __devinit etm_arch_supported(uint8_t arch)
+{
+	switch (arch) {
+	case PFT_ARCH_V1_1:
+		break;
+	default:
+		return false;
+	}
+	return true;
+}
+
+static int __devinit etm_init_arch_data(void)
+{
+	int ret;
+	/* use cpu 0 for setup */
+	int cpu = 0;
+	uint32_t etmidr;
+	uint32_t etmccr;
+
+	/* Unlock OS lock first to allow memory mapped reads and writes */
+	etm_os_unlock(NULL);
+	smp_call_function(etm_os_unlock, NULL, 1);
+	ETM_UNLOCK(cpu);
+	/* Vote for ETM power/clock enable */
+	etm_clr_pwrdwn(cpu);
+	/* Set prog bit. It will be set from reset but this is included to
+	 * ensure it is set
+	 */
+	etm_set_prog(cpu);
+
+	/* find all capabilities */
+	etmidr = etm_readl(drvdata, cpu, ETMIDR);
+	drvdata->arch = BMVAL(etmidr, 4, 11);
+	if (etm_arch_supported(drvdata->arch) == false) {
+		ret = -EINVAL;
+		goto err;
+	}
+
+	etmccr = etm_readl(drvdata, cpu, ETMCCR);
+	drvdata->nr_addr_cmp = BMVAL(etmccr, 0, 3) * 2;
+	drvdata->nr_cntr = BMVAL(etmccr, 13, 15);
+	drvdata->nr_ext_inp = BMVAL(etmccr, 17, 19);
+	drvdata->nr_ext_out = BMVAL(etmccr, 20, 22);
+	drvdata->nr_ctxid_cmp = BMVAL(etmccr, 24, 25);
+
+	/* Vote for ETM power/clock disable */
+	etm_set_pwrdwn(cpu);
+	ETM_LOCK(cpu);
+
+	return 0;
+err:
+	return ret;
+}
+
+static void __devinit etm_init_default_data(void)
+{
+	int i;
+
+	drvdata->trigger_event = 0x406F;
+	drvdata->enable_event = 0x6F;
+	drvdata->enable_ctrl1 = 0x1;
+	drvdata->fifofull_level	= 0x28;
+	if (drvdata->nr_addr_cmp >= 2) {
+		drvdata->addr_val[0] = (uint32_t) _stext;
+		drvdata->addr_val[1] = (uint32_t) _etext;
+		drvdata->addr_type[0] = ETM_ADDR_TYPE_RANGE;
+		drvdata->addr_type[1] = ETM_ADDR_TYPE_RANGE;
+	}
+	for (i = 0; i < drvdata->nr_cntr; i++) {
+		drvdata->cntr_event[i] = 0x406F;
+		drvdata->cntr_rld_event[i] = 0x406F;
+	}
+	drvdata->seq_12_event = 0x406F;
+	drvdata->seq_21_event = 0x406F;
+	drvdata->seq_23_event = 0x406F;
+	drvdata->seq_31_event = 0x406F;
+	drvdata->seq_32_event = 0x406F;
+	drvdata->seq_13_event = 0x406F;
+	drvdata->sync_freq = 0x80;
+	drvdata->timestamp_event = 0x406F;
+
+	/* Overrides for Krait pass1 */
+	if (cpu_is_krait_v1()) {
+		/* Krait pass1 doesn't support include filtering and non-cycle
+		 * accurate tracing
+		 */
+		drvdata->mode = (ETM_MODE_EXCLUDE | ETM_MODE_CYCACC);
+		drvdata->ctrl = 0x1000;
+		drvdata->enable_ctrl1 = 0x1000000;
+		for (i = 0; i < drvdata->nr_addr_cmp; i++) {
+			drvdata->addr_val[i] = 0x0;
+			drvdata->addr_acctype[i] = 0x0;
+			drvdata->addr_type[i] = ETM_ADDR_TYPE_NONE;
+		}
+	}
+}
+
+static int __devinit etm_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct resource *res;
+
+	drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata) {
+		ret = -ENOMEM;
+		goto err_kzalloc_drvdata;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		ret = -EINVAL;
+		goto err_res;
+	}
+
+	drvdata->base = ioremap_nocache(res->start, resource_size(res));
+	if (!drvdata->base) {
+		ret = -EINVAL;
+		goto err_ioremap;
+	}
+
+	drvdata->dev = &pdev->dev;
+
+	mutex_init(&drvdata->mutex);
+	wake_lock_init(&drvdata->wake_lock, WAKE_LOCK_SUSPEND, "msm_etm");
+	pm_qos_add_request(&drvdata->qos_req, PM_QOS_CPU_DMA_LATENCY,
+			   PM_QOS_DEFAULT_VALUE);
+	drvdata->src = qdss_get("msm_etm");
+	if (IS_ERR(drvdata->src)) {
+		ret = PTR_ERR(drvdata->src);
+		goto err_qdssget;
+	}
+
+	drvdata->clk = clk_get(drvdata->dev, "core_clk");
+	if (IS_ERR(drvdata->clk)) {
+		ret = PTR_ERR(drvdata->clk);
+		goto err_clk_get;
+	}
+
+	ret = clk_set_rate(drvdata->clk, CORESIGHT_CLK_RATE_TRACE);
+	if (ret)
+		goto err_clk_rate;
+
+	ret = clk_prepare_enable(drvdata->clk);
+	if (ret)
+		goto err_clk_enable;
+
+	ret = etm_init_arch_data();
+	if (ret)
+		goto err_arch;
+
+	etm_init_default_data();
+
+	ret = etm_sysfs_init();
+	if (ret)
+		goto err_sysfs;
+
+	drvdata->enabled = false;
+
+	clk_disable_unprepare(drvdata->clk);
+
+	dev_info(drvdata->dev, "ETM initialized\n");
+
+	if (etm_boot_enable)
+		etm_enable();
+
+	return 0;
+
+err_sysfs:
+err_arch:
+	clk_disable_unprepare(drvdata->clk);
+err_clk_enable:
+err_clk_rate:
+	clk_put(drvdata->clk);
+err_clk_get:
+	qdss_put(drvdata->src);
+err_qdssget:
+	pm_qos_remove_request(&drvdata->qos_req);
+	wake_lock_destroy(&drvdata->wake_lock);
+	mutex_destroy(&drvdata->mutex);
+	iounmap(drvdata->base);
+err_ioremap:
+err_res:
+	kfree(drvdata);
+err_kzalloc_drvdata:
+	dev_err(drvdata->dev, "ETM init failed\n");
+	return ret;
+}
+
+static int __devexit etm_remove(struct platform_device *pdev)
+{
+	if (drvdata->enabled)
+		etm_disable();
+	etm_sysfs_exit();
+	clk_put(drvdata->clk);
+	qdss_put(drvdata->src);
+	pm_qos_remove_request(&drvdata->qos_req);
+	wake_lock_destroy(&drvdata->wake_lock);
+	mutex_destroy(&drvdata->mutex);
+	iounmap(drvdata->base);
+	kfree(drvdata);
+
+	return 0;
+}
+
+static struct of_device_id etm_match[] = {
+	{.compatible = "qcom,msm-etm"},
+	{}
+};
+
+static struct platform_driver etm_driver = {
+	.probe          = etm_probe,
+	.remove         = __devexit_p(etm_remove),
+	.driver         = {
+		.name   = "msm_etm",
+		.owner	= THIS_MODULE,
+		.of_match_table = etm_match,
+	},
+};
+
+int __init etm_init(void)
+{
+	return platform_driver_register(&etm_driver);
+}
+module_init(etm_init);
+
+void __exit etm_exit(void)
+{
+	platform_driver_unregister(&etm_driver);
+}
+module_exit(etm_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("CoreSight Program Flow Trace driver");
diff --git a/drivers/coresight/coresight-funnel.c b/drivers/coresight/coresight-funnel.c
new file mode 100644
index 0000000..79a27f4
--- /dev/null
+++ b/drivers/coresight/coresight-funnel.c
@@ -0,0 +1,275 @@
+/* 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
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/coresight.h>
+
+#include "coresight-priv.h"
+
+#define funnel_writel(drvdata, id, val, off)	\
+			__raw_writel((val), drvdata->base + (SZ_4K * id) + off)
+#define funnel_readl(drvdata, id, off)		\
+			__raw_readl(drvdata->base + (SZ_4K * id) + off)
+
+#define FUNNEL_FUNCTL			(0x000)
+#define FUNNEL_PRICTL			(0x004)
+#define FUNNEL_ITATBDATA0		(0xEEC)
+#define FUNNEL_ITATBCTR2		(0xEF0)
+#define FUNNEL_ITATBCTR1		(0xEF4)
+#define FUNNEL_ITATBCTR0		(0xEF8)
+
+
+#define FUNNEL_LOCK(id)							\
+do {									\
+	mb();								\
+	funnel_writel(drvdata, id, 0x0, CORESIGHT_LAR);			\
+} while (0)
+#define FUNNEL_UNLOCK(id)						\
+do {									\
+	funnel_writel(drvdata, id, CORESIGHT_UNLOCK, CORESIGHT_LAR);	\
+	mb();								\
+} while (0)
+
+#define FUNNEL_HOLDTIME_MASK		(0xF00)
+#define FUNNEL_HOLDTIME_SHFT		(0x8)
+#define FUNNEL_HOLDTIME			(0x7 << FUNNEL_HOLDTIME_SHFT)
+
+struct funnel_drvdata {
+	void __iomem	*base;
+	bool		enabled;
+	struct mutex	mutex;
+	struct device	*dev;
+	struct kobject	*kobj;
+	struct clk	*clk;
+	uint32_t	priority;
+};
+
+static struct funnel_drvdata *drvdata;
+
+static void __funnel_enable(uint8_t id, uint32_t port_mask)
+{
+	uint32_t functl;
+
+	FUNNEL_UNLOCK(id);
+
+	functl = funnel_readl(drvdata, id, FUNNEL_FUNCTL);
+	functl &= ~FUNNEL_HOLDTIME_MASK;
+	functl |= FUNNEL_HOLDTIME;
+	functl |= port_mask;
+	funnel_writel(drvdata, id, functl, FUNNEL_FUNCTL);
+	funnel_writel(drvdata, id, drvdata->priority, FUNNEL_PRICTL);
+
+	FUNNEL_LOCK(id);
+}
+
+int funnel_enable(uint8_t id, uint32_t port_mask)
+{
+	int ret;
+
+	ret = clk_prepare_enable(drvdata->clk);
+	if (ret)
+		return ret;
+
+	mutex_lock(&drvdata->mutex);
+	__funnel_enable(id, port_mask);
+	drvdata->enabled = true;
+	dev_info(drvdata->dev, "FUNNEL port mask 0x%lx enabled\n",
+					(unsigned long) port_mask);
+	mutex_unlock(&drvdata->mutex);
+
+	return 0;
+}
+
+static void __funnel_disable(uint8_t id, uint32_t port_mask)
+{
+	uint32_t functl;
+
+	FUNNEL_UNLOCK(id);
+
+	functl = funnel_readl(drvdata, id, FUNNEL_FUNCTL);
+	functl &= ~port_mask;
+	funnel_writel(drvdata, id, functl, FUNNEL_FUNCTL);
+
+	FUNNEL_LOCK(id);
+}
+
+void funnel_disable(uint8_t id, uint32_t port_mask)
+{
+	mutex_lock(&drvdata->mutex);
+	__funnel_disable(id, port_mask);
+	drvdata->enabled = false;
+	dev_info(drvdata->dev, "FUNNEL port mask 0x%lx disabled\n",
+					(unsigned long) port_mask);
+	mutex_unlock(&drvdata->mutex);
+
+	clk_disable_unprepare(drvdata->clk);
+}
+
+static ssize_t funnel_show_priority(struct device *dev,
+				    struct device_attribute *attr, char *buf)
+{
+	unsigned long val = drvdata->priority;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t funnel_store_priority(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t size)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	drvdata->priority = val;
+	return size;
+}
+static DEVICE_ATTR(priority, S_IRUGO | S_IWUSR, funnel_show_priority,
+		   funnel_store_priority);
+
+static int __devinit funnel_sysfs_init(void)
+{
+	int ret;
+
+	drvdata->kobj = kobject_create_and_add("funnel", qdss_get_modulekobj());
+	if (!drvdata->kobj) {
+		dev_err(drvdata->dev, "failed to create FUNNEL sysfs kobject\n");
+		ret = -ENOMEM;
+		goto err_create;
+	}
+
+	ret = sysfs_create_file(drvdata->kobj, &dev_attr_priority.attr);
+	if (ret) {
+		dev_err(drvdata->dev, "failed to create FUNNEL sysfs priority"
+		" attribute\n");
+		goto err_file;
+	}
+
+	return 0;
+err_file:
+	kobject_put(drvdata->kobj);
+err_create:
+	return ret;
+}
+
+static void __devexit funnel_sysfs_exit(void)
+{
+	sysfs_remove_file(drvdata->kobj, &dev_attr_priority.attr);
+	kobject_put(drvdata->kobj);
+}
+
+static int __devinit funnel_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct resource *res;
+
+	drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata) {
+		ret = -ENOMEM;
+		goto err_kzalloc_drvdata;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		ret = -EINVAL;
+		goto err_res;
+	}
+
+	drvdata->base = ioremap_nocache(res->start, resource_size(res));
+	if (!drvdata->base) {
+		ret = -EINVAL;
+		goto err_ioremap;
+	}
+
+	drvdata->dev = &pdev->dev;
+
+	mutex_init(&drvdata->mutex);
+
+	drvdata->clk = clk_get(drvdata->dev, "core_clk");
+	if (IS_ERR(drvdata->clk)) {
+		ret = PTR_ERR(drvdata->clk);
+		goto err_clk_get;
+	}
+
+	ret = clk_set_rate(drvdata->clk, CORESIGHT_CLK_RATE_TRACE);
+	if (ret)
+		goto err_clk_rate;
+
+	funnel_sysfs_init();
+
+	dev_info(drvdata->dev, "FUNNEL initialized\n");
+	return 0;
+
+err_clk_rate:
+	clk_put(drvdata->clk);
+err_clk_get:
+	mutex_destroy(&drvdata->mutex);
+	iounmap(drvdata->base);
+err_ioremap:
+err_res:
+	kfree(drvdata);
+err_kzalloc_drvdata:
+	dev_err(drvdata->dev, "FUNNEL init failed\n");
+	return ret;
+}
+
+static int __devexit funnel_remove(struct platform_device *pdev)
+{
+	if (drvdata->enabled)
+		funnel_disable(0x0, 0xFF);
+	funnel_sysfs_exit();
+	clk_put(drvdata->clk);
+	mutex_destroy(&drvdata->mutex);
+	iounmap(drvdata->base);
+	kfree(drvdata);
+
+	return 0;
+}
+
+static struct of_device_id funnel_match[] = {
+	{.compatible = "qcom,msm-funnel"},
+	{}
+};
+
+static struct platform_driver funnel_driver = {
+	.probe          = funnel_probe,
+	.remove         = __devexit_p(funnel_remove),
+	.driver         = {
+		.name   = "msm_funnel",
+		.owner	= THIS_MODULE,
+		.of_match_table = funnel_match,
+	},
+};
+
+static int __init funnel_init(void)
+{
+	return platform_driver_register(&funnel_driver);
+}
+module_init(funnel_init);
+
+static void __exit funnel_exit(void)
+{
+	platform_driver_unregister(&funnel_driver);
+}
+module_exit(funnel_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("CoreSight Funnel driver");
diff --git a/drivers/coresight/coresight-priv.h b/drivers/coresight/coresight-priv.h
new file mode 100644
index 0000000..dab854c
--- /dev/null
+++ b/drivers/coresight/coresight-priv.h
@@ -0,0 +1,48 @@
+/* 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
+ * 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 _CORESIGHT_PRIV_H
+#define _CORESIGHT_PRIV_H
+
+#include <linux/bitops.h>
+
+/* Coresight management registers (0xF00-0xFCC)
+ * 0xFA0 - 0xFA4: Management	registers in PFTv1.0
+ *		  Trace		registers in PFTv1.1
+ */
+#define CORESIGHT_ITCTRL	(0xF00)
+#define CORESIGHT_CLAIMSET	(0xFA0)
+#define CORESIGHT_CLAIMCLR	(0xFA4)
+#define CORESIGHT_LAR		(0xFB0)
+#define CORESIGHT_LSR		(0xFB4)
+#define CORESIGHT_AUTHSTATUS	(0xFB8)
+#define CORESIGHT_DEVID		(0xFC8)
+#define CORESIGHT_DEVTYPE	(0xFCC)
+
+#define CORESIGHT_UNLOCK	(0xC5ACCE55)
+
+#define TIMEOUT_US		(100)
+
+#define BM(lsb, msb)		((BIT(msb) - BIT(lsb)) + BIT(msb))
+#define BMVAL(val, lsb, msb)	((val & BM(lsb, msb)) >> lsb)
+#define BVAL(val, n)		((val & BIT(n)) >> n)
+
+int etb_enable(void);
+void etb_disable(void);
+void etb_dump(void);
+void tpiu_disable(void);
+int funnel_enable(uint8_t id, uint32_t port_mask);
+void funnel_disable(uint8_t id, uint32_t port_mask);
+
+struct kobject *qdss_get_modulekobj(void);
+
+#endif
diff --git a/arch/arm/mach-msm/qdss-stm.c b/drivers/coresight/coresight-stm.c
similarity index 67%
rename from arch/arm/mach-msm/qdss-stm.c
rename to drivers/coresight/coresight-stm.c
index 0d44c1a..6387947 100644
--- a/arch/arm/mach-msm/qdss-stm.c
+++ b/drivers/coresight/coresight-stm.c
@@ -22,15 +22,17 @@
 #include <linux/miscdevice.h>
 #include <linux/uaccess.h>
 #include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/coresight.h>
+#include <linux/coresight-stm.h>
 #include <asm/unaligned.h>
-#include <mach/stm.h>
 
-#include "qdss-priv.h"
+#include "coresight-priv.h"
 
-#define stm_writel(stm, val, off)	\
-			__raw_writel((val), stm.base + off)
-#define stm_readl(stm, val, off)	\
-			__raw_readl(stm.base + off)
+#define stm_writel(drvdata, val, off)	\
+			__raw_writel((val), drvdata->base + off)
+#define stm_readl(drvdata, val, off)	\
+			__raw_readl(drvdata->base + off)
 
 #define NR_STM_CHANNEL		(32)
 #define BYTES_PER_CHANNEL	(256)
@@ -51,17 +53,17 @@
 #define OST_VERSION		(0x1)
 
 #define stm_channel_addr(ch)						\
-				(stm.chs.base + (ch * BYTES_PER_CHANNEL))
+				(drvdata->chs.base + (ch * BYTES_PER_CHANNEL))
 #define stm_channel_off(type, opts)	(type & ~opts)
 
 #define STM_LOCK()							\
 do {									\
 	mb();								\
-	stm_writel(stm, 0x0, CS_LAR);					\
+	stm_writel(drvdata, 0x0, CORESIGHT_LAR);			\
 } while (0)
 #define STM_UNLOCK()							\
 do {									\
-	stm_writel(stm, CS_UNLOCK_MAGIC, CS_LAR);			\
+	stm_writel(drvdata, CORESIGHT_UNLOCK, CORESIGHT_LAR);		\
 	mb();								\
 } while (0)
 
@@ -91,29 +93,27 @@
 	unsigned long		*bitmap;
 };
 
-struct stm_ctx {
+struct stm_drvdata {
 	void __iomem		*base;
 	bool			enabled;
 	struct qdss_source	*src;
 	struct device		*dev;
 	struct kobject		*kobj;
+	struct clk		*clk;
 	uint32_t		entity;
 	struct channel_space	chs;
 };
 
-static struct stm_ctx stm = {
-	.entity		= OST_ENTITY_ALL,
-};
-
+static struct stm_drvdata *drvdata;
 
 static void __stm_enable(void)
 {
 	STM_UNLOCK();
 
-	stm_writel(stm, 0x80, STMSYNCR);
-	stm_writel(stm, 0xFFFFFFFF, STMSPTER);
-	stm_writel(stm, 0xFFFFFFFF, STMSPER);
-	stm_writel(stm, 0x30003, STMTCSR);
+	stm_writel(drvdata, 0x80, STMSYNCR);
+	stm_writel(drvdata, 0xFFFFFFFF, STMSPTER);
+	stm_writel(drvdata, 0xFFFFFFFF, STMSPER);
+	stm_writel(drvdata, 0x30003, STMTCSR);
 
 	STM_LOCK();
 }
@@ -122,23 +122,30 @@
 {
 	int ret;
 
-	if (stm.enabled) {
-		dev_err(stm.dev, "STM tracing already enabled\n");
+	if (drvdata->enabled) {
+		dev_err(drvdata->dev, "STM tracing already enabled\n");
 		ret = -EINVAL;
 		goto err;
 	}
 
-	ret = qdss_enable(stm.src);
+	ret = clk_prepare_enable(drvdata->clk);
 	if (ret)
-		goto err;
+		goto err_clk;
+
+	ret = qdss_enable(drvdata->src);
+	if (ret)
+		goto err_qdss;
 
 	__stm_enable();
 
-	stm.enabled = true;
+	drvdata->enabled = true;
 
-	dev_info(stm.dev, "STM tracing enabled\n");
+	dev_info(drvdata->dev, "STM tracing enabled\n");
 	return 0;
 
+err_qdss:
+	clk_disable_unprepare(drvdata->clk);
+err_clk:
 err:
 	return ret;
 }
@@ -147,9 +154,9 @@
 {
 	STM_UNLOCK();
 
-	stm_writel(stm, 0x30000, STMTCSR);
-	stm_writel(stm, 0x0, STMSPER);
-	stm_writel(stm, 0x0, STMSPTER);
+	stm_writel(drvdata, 0x30000, STMTCSR);
+	stm_writel(drvdata, 0x0, STMSPER);
+	stm_writel(drvdata, 0x0, STMSPTER);
 
 	STM_LOCK();
 }
@@ -158,19 +165,21 @@
 {
 	int ret;
 
-	if (!stm.enabled) {
-		dev_err(stm.dev, "STM tracing already disabled\n");
+	if (!drvdata->enabled) {
+		dev_err(drvdata->dev, "STM tracing already disabled\n");
 		ret = -EINVAL;
 		goto err;
 	}
 
 	__stm_disable();
 
-	qdss_disable(stm.src);
+	drvdata->enabled = false;
 
-	stm.enabled = false;
+	qdss_disable(drvdata->src);
 
-	dev_info(stm.dev, "STM tracing disabled\n");
+	clk_disable_unprepare(drvdata->clk);
+
+	dev_info(drvdata->dev, "STM tracing disabled\n");
 	return 0;
 
 err:
@@ -182,15 +191,17 @@
 	uint32_t ch;
 
 	do {
-		ch = find_next_zero_bit(stm.chs.bitmap,	NR_STM_CHANNEL, off);
-	} while ((ch < NR_STM_CHANNEL) && test_and_set_bit(ch, stm.chs.bitmap));
+		ch = find_next_zero_bit(drvdata->chs.bitmap,
+					NR_STM_CHANNEL, off);
+	} while ((ch < NR_STM_CHANNEL) &&
+		 test_and_set_bit(ch, drvdata->chs.bitmap));
 
 	return ch;
 }
 
 static void stm_channel_free(uint32_t ch)
 {
-	clear_bit(ch, stm.chs.bitmap);
+	clear_bit(ch, drvdata->chs.bitmap);
 }
 
 static int stm_send(void *addr, const void *data, uint32_t size)
@@ -331,10 +342,10 @@
  * number of bytes transfered over STM
  */
 int stm_trace(uint32_t options, uint8_t entity_id, uint8_t proto_id,
-	      const void *data, uint32_t size)
+			const void *data, uint32_t size)
 {
 	/* we don't support sizes more than 24bits (0 to 23) */
-	if (!(stm.enabled && (stm.entity & entity_id) &&
+	if (!(drvdata->enabled && (drvdata->entity & entity_id) &&
 	      (size < 0x1000000)))
 		return 0;
 
@@ -347,10 +358,10 @@
 {
 	char *buf;
 
-	if (!stm.enabled)
+	if (!drvdata->enabled)
 		return -EINVAL;
 
-	if (!(stm.entity & OST_ENTITY_DEV_NODE))
+	if (!(drvdata->entity & OST_ENTITY_DEV_NODE))
 		return size;
 
 	if (size > STM_TRACE_BUF_SIZE)
@@ -362,7 +373,7 @@
 
 	if (copy_from_user(buf, data, size)) {
 		kfree(buf);
-		dev_dbg(stm.dev, "%s: copy_from_user failed\n", __func__);
+		dev_dbg(drvdata->dev, "%s: copy_from_user failed\n", __func__);
 		return -EFAULT;
 	}
 
@@ -385,13 +396,16 @@
 	.fops		= &stm_fops,
 };
 
-#define STM_ATTR(__name)						\
-static struct kobj_attribute __name##_attr =				\
-	__ATTR(__name, S_IRUGO | S_IWUSR, __name##_show, __name##_store)
+static ssize_t stm_show_enabled(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	unsigned long val = drvdata->enabled;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
 
-static ssize_t enabled_store(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			const char *buf, size_t n)
+static ssize_t stm_store_enabled(struct device *dev,
+				 struct device_attribute *attr,
+				const char *buf, size_t size)
 {
 	int ret = 0;
 	unsigned long val;
@@ -406,70 +420,65 @@
 
 	if (ret)
 		return ret;
-	return n;
+	return size;
 }
-static ssize_t enabled_show(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			char *buf)
+static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, stm_show_enabled,
+		   stm_store_enabled);
+
+static ssize_t stm_show_entity(struct device *dev,
+			       struct device_attribute *attr, char *buf)
 {
-	unsigned long val = stm.enabled;
+	unsigned long val = drvdata->entity;
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
-STM_ATTR(enabled);
 
-static ssize_t entity_store(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			const char *buf, size_t n)
+static ssize_t stm_store_entity(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t size)
 {
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
 		return -EINVAL;
 
-	stm.entity = val;
-	return n;
+	drvdata->entity = val;
+	return size;
 }
-static ssize_t entity_show(struct kobject *kobj,
-			struct kobj_attribute *attr,
-			char *buf)
-{
-	unsigned long val = stm.entity;
-	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
-}
-STM_ATTR(entity);
+static DEVICE_ATTR(entity, S_IRUGO | S_IWUSR, stm_show_entity,
+		   stm_store_entity);
 
 static int __devinit stm_sysfs_init(void)
 {
 	int ret;
 
-	stm.kobj = kobject_create_and_add("stm", qdss_get_modulekobj());
-	if (!stm.kobj) {
-		dev_err(stm.dev, "failed to create STM sysfs kobject\n");
+	drvdata->kobj = kobject_create_and_add("stm", qdss_get_modulekobj());
+	if (!drvdata->kobj) {
+		dev_err(drvdata->dev, "failed to create STM sysfs kobject\n");
 		ret = -ENOMEM;
 		goto err_create;
 	}
 
-	ret = sysfs_create_file(stm.kobj, &enabled_attr.attr);
+	ret = sysfs_create_file(drvdata->kobj, &dev_attr_enabled.attr);
 	if (ret) {
-		dev_err(stm.dev, "failed to create STM sysfs enabled attr\n");
+		dev_err(drvdata->dev, "failed to create STM sysfs enabled attr\n");
 		goto err_file;
 	}
 
-	if (sysfs_create_file(stm.kobj, &entity_attr.attr))
-		dev_err(stm.dev, "failed to create STM sysfs entity attr\n");
+	if (sysfs_create_file(drvdata->kobj, &dev_attr_entity.attr))
+		dev_err(drvdata->dev, "failed to create STM sysfs entity attr\n");
 
 	return 0;
 err_file:
-	kobject_put(stm.kobj);
+	kobject_put(drvdata->kobj);
 err_create:
 	return ret;
 }
 
 static void __devexit stm_sysfs_exit(void)
 {
-	sysfs_remove_file(stm.kobj, &entity_attr.attr);
-	sysfs_remove_file(stm.kobj, &enabled_attr.attr);
-	kobject_put(stm.kobj);
+	sysfs_remove_file(drvdata->kobj, &dev_attr_entity.attr);
+	sysfs_remove_file(drvdata->kobj, &dev_attr_enabled.attr);
+	kobject_put(drvdata->kobj);
 }
 
 static int __devinit stm_probe(struct platform_device *pdev)
@@ -478,14 +487,20 @@
 	struct resource *res;
 	size_t res_size, bitmap_size;
 
+	drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata) {
+		ret = -ENOMEM;
+		goto err_kzalloc_drvdata;
+	}
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 		ret = -EINVAL;
 		goto err_res0;
 	}
 
-	stm.base = ioremap_nocache(res->start, resource_size(res));
-	if (!stm.base) {
+	drvdata->base = ioremap_nocache(res->start, resource_size(res));
+	if (!drvdata->base) {
 		ret = -EINVAL;
 		goto err_ioremap0;
 	}
@@ -506,30 +521,42 @@
 		bitmap_size = NR_STM_CHANNEL * sizeof(long);
 	}
 
-	stm.chs.bitmap = kzalloc(bitmap_size, GFP_KERNEL);
-	if (!stm.chs.bitmap) {
+	drvdata->chs.bitmap = kzalloc(bitmap_size, GFP_KERNEL);
+	if (!drvdata->chs.bitmap) {
 		ret = -ENOMEM;
 		goto err_bitmap;
 	}
 
-	stm.chs.base = ioremap_nocache(res->start, res_size);
-	if (!stm.chs.base) {
+	drvdata->chs.base = ioremap_nocache(res->start, res_size);
+	if (!drvdata->chs.base) {
 		ret = -EINVAL;
 		goto err_ioremap1;
 	}
 
-	stm.dev = &pdev->dev;
+	drvdata->dev = &pdev->dev;
 
 	ret = misc_register(&stm_misc);
 	if (ret)
 		goto err_misc;
 
-	stm.src = qdss_get("msm_stm");
-	if (IS_ERR(stm.src)) {
-		ret = PTR_ERR(stm.src);
+	drvdata->src = qdss_get("msm_stm");
+	if (IS_ERR(drvdata->src)) {
+		ret = PTR_ERR(drvdata->src);
 		goto err_qdssget;
 	}
 
+	drvdata->clk = clk_get(drvdata->dev, "core_clk");
+	if (IS_ERR(drvdata->clk)) {
+		ret = PTR_ERR(drvdata->clk);
+		goto err_clk_get;
+	}
+
+	ret = clk_set_rate(drvdata->clk, CORESIGHT_CLK_RATE_TRACE);
+	if (ret)
+		goto err_clk_rate;
+
+	drvdata->entity = OST_ENTITY_ALL;
+
 	ret = stm_sysfs_init();
 	if (ret)
 		goto err_sysfs;
@@ -537,36 +564,44 @@
 	if (stm_boot_enable)
 		stm_enable();
 
-	dev_info(stm.dev, "STM initialized\n");
+	dev_info(drvdata->dev, "STM initialized\n");
 	return 0;
 
 err_sysfs:
-	qdss_put(stm.src);
+err_clk_rate:
+	clk_put(drvdata->clk);
+err_clk_get:
+	qdss_put(drvdata->src);
 err_qdssget:
 	misc_deregister(&stm_misc);
 err_misc:
-	iounmap(stm.chs.base);
+	iounmap(drvdata->chs.base);
 err_ioremap1:
-	kfree(stm.chs.bitmap);
+	kfree(drvdata->chs.bitmap);
 err_bitmap:
 err_res1:
-	iounmap(stm.base);
+	iounmap(drvdata->base);
 err_ioremap0:
 err_res0:
-	dev_err(stm.dev, "STM init failed\n");
+	kfree(drvdata);
+err_kzalloc_drvdata:
+
+	dev_err(drvdata->dev, "STM init failed\n");
 	return ret;
 }
 
 static int __devexit stm_remove(struct platform_device *pdev)
 {
-	if (stm.enabled)
+	if (drvdata->enabled)
 		stm_disable();
 	stm_sysfs_exit();
-	qdss_put(stm.src);
+	clk_put(drvdata->clk);
+	qdss_put(drvdata->src);
 	misc_deregister(&stm_misc);
-	iounmap(stm.chs.base);
-	kfree(stm.chs.bitmap);
-	iounmap(stm.base);
+	iounmap(drvdata->chs.base);
+	kfree(drvdata->chs.bitmap);
+	iounmap(drvdata->base);
+	kfree(drvdata);
 
 	return 0;
 }
diff --git a/arch/arm/mach-msm/qdss-tpiu.c b/drivers/coresight/coresight-tpiu.c
similarity index 66%
rename from arch/arm/mach-msm/qdss-tpiu.c
rename to drivers/coresight/coresight-tpiu.c
index 23905f0..4b52c4d 100644
--- a/arch/arm/mach-msm/qdss-tpiu.c
+++ b/drivers/coresight/coresight-tpiu.c
@@ -17,11 +17,14 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/coresight.h>
 
-#include "qdss-priv.h"
+#include "coresight-priv.h"
 
-#define tpiu_writel(tpiu, val, off)	__raw_writel((val), tpiu.base + off)
-#define tpiu_readl(tpiu, off)		__raw_readl(tpiu.base + off)
+#define tpiu_writel(drvdata, val, off)	__raw_writel((val), drvdata->base + off)
+#define tpiu_readl(drvdata, off)	__raw_readl(drvdata->base + off)
 
 #define TPIU_SUPP_PORTSZ				(0x000)
 #define TPIU_CURR_PORTSZ				(0x004)
@@ -47,28 +50,29 @@
 #define TPIU_LOCK()							\
 do {									\
 	mb();								\
-	tpiu_writel(tpiu, 0x0, CS_LAR);					\
+	tpiu_writel(drvdata, 0x0, CORESIGHT_LAR);			\
 } while (0)
 #define TPIU_UNLOCK()							\
 do {									\
-	tpiu_writel(tpiu, CS_UNLOCK_MAGIC, CS_LAR);			\
+	tpiu_writel(drvdata, CORESIGHT_UNLOCK, CORESIGHT_LAR);		\
 	mb();								\
 } while (0)
 
-struct tpiu_ctx {
+struct tpiu_drvdata {
 	void __iomem	*base;
 	bool		enabled;
 	struct device	*dev;
+	struct clk	*clk;
 };
 
-static struct tpiu_ctx tpiu;
+static struct tpiu_drvdata *drvdata;
 
 static void __tpiu_disable(void)
 {
 	TPIU_UNLOCK();
 
-	tpiu_writel(tpiu, 0x3000, TPIU_FFCR);
-	tpiu_writel(tpiu, 0x3040, TPIU_FFCR);
+	tpiu_writel(drvdata, 0x3000, TPIU_FFCR);
+	tpiu_writel(drvdata, 0x3040, TPIU_FFCR);
 
 	TPIU_LOCK();
 }
@@ -76,8 +80,8 @@
 void tpiu_disable(void)
 {
 	__tpiu_disable();
-	tpiu.enabled = false;
-	dev_info(tpiu.dev, "TPIU disabled\n");
+	drvdata->enabled = false;
+	dev_info(drvdata->dev, "TPIU disabled\n");
 }
 
 static int __devinit tpiu_probe(struct platform_device *pdev)
@@ -85,34 +89,58 @@
 	int ret;
 	struct resource *res;
 
+	drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata) {
+		ret = -ENOMEM;
+		goto err_kzalloc_drvdata;
+	}
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 		ret = -EINVAL;
 		goto err_res;
 	}
 
-	tpiu.base = ioremap_nocache(res->start, resource_size(res));
-	if (!tpiu.base) {
+	drvdata->base = ioremap_nocache(res->start, resource_size(res));
+	if (!drvdata->base) {
 		ret = -EINVAL;
 		goto err_ioremap;
 	}
 
-	tpiu.dev = &pdev->dev;
+	drvdata->dev = &pdev->dev;
 
-	dev_info(tpiu.dev, "TPIU initialized\n");
+	drvdata->clk = clk_get(drvdata->dev, "core_clk");
+	if (IS_ERR(drvdata->clk)) {
+		ret = PTR_ERR(drvdata->clk);
+		goto err_clk_get;
+	}
+
+	ret = clk_set_rate(drvdata->clk, CORESIGHT_CLK_RATE_TRACE);
+	if (ret)
+		goto err_clk_rate;
+
+	dev_info(drvdata->dev, "TPIU initialized\n");
 	return 0;
 
+err_clk_rate:
+	clk_put(drvdata->clk);
+err_clk_get:
+	iounmap(drvdata->base);
 err_ioremap:
 err_res:
-	dev_err(tpiu.dev, "TPIU init failed\n");
+	kfree(drvdata);
+err_kzalloc_drvdata:
+	dev_err(drvdata->dev, "TPIU init failed\n");
 	return ret;
 }
 
 static int __devexit tpiu_remove(struct platform_device *pdev)
 {
-	if (tpiu.enabled)
+	if (drvdata->enabled)
 		tpiu_disable();
-	iounmap(tpiu.base);
+	clk_put(drvdata->clk);
+	iounmap(drvdata->base);
+	kfree(drvdata);
 
 	return 0;
 }
diff --git a/drivers/coresight/coresight.c b/drivers/coresight/coresight.c
new file mode 100644
index 0000000..055ef55
--- /dev/null
+++ b/drivers/coresight/coresight.c
@@ -0,0 +1,606 @@
+/* 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/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/export.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/clk.h>
+#include <linux/coresight.h>
+
+#include "coresight-priv.h"
+
+#define MAX_STR_LEN	(65535)
+
+
+static LIST_HEAD(coresight_orph_conns);
+static DEFINE_MUTEX(coresight_conns_mutex);
+static LIST_HEAD(coresight_devs);
+static DEFINE_MUTEX(coresight_devs_mutex);
+
+
+int coresight_enable(struct coresight_device *csdev, int port)
+{
+	int i;
+	int ret;
+	struct coresight_connection *conn;
+
+	mutex_lock(&csdev->mutex);
+	if (csdev->refcnt[port] == 0) {
+		for (i = 0; i < csdev->nr_conns; i++) {
+			conn = &csdev->conns[i];
+			ret = coresight_enable(conn->child_dev,
+					       conn->child_port);
+			if (ret)
+				goto err_enable_child;
+		}
+		if (csdev->ops->enable)
+			ret = csdev->ops->enable(csdev, port);
+		if (ret)
+			goto err_enable;
+	}
+	csdev->refcnt[port]++;
+	mutex_unlock(&csdev->mutex);
+	return 0;
+err_enable_child:
+	while (i) {
+		conn = &csdev->conns[--i];
+		coresight_disable(conn->child_dev, conn->child_port);
+	}
+err_enable:
+	mutex_unlock(&csdev->mutex);
+	return ret;
+}
+EXPORT_SYMBOL(coresight_enable);
+
+void coresight_disable(struct coresight_device *csdev, int port)
+{
+	int i;
+	struct coresight_connection *conn;
+
+	mutex_lock(&csdev->mutex);
+	if (csdev->refcnt[port] == 1) {
+		if (csdev->ops->disable)
+			csdev->ops->disable(csdev, port);
+		for (i = 0; i < csdev->nr_conns; i++) {
+			conn = &csdev->conns[i];
+			coresight_disable(conn->child_dev, conn->child_port);
+		}
+	}
+	csdev->refcnt[port]--;
+	mutex_unlock(&csdev->mutex);
+}
+EXPORT_SYMBOL(coresight_disable);
+
+static ssize_t coresight_show_type(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%s\n", dev->type->name);
+}
+
+static struct device_attribute coresight_dev_attrs[] = {
+	__ATTR(type, S_IRUGO, coresight_show_type, NULL),
+	{ },
+};
+
+struct bus_type coresight_bus_type = {
+	.name		= "coresight",
+	.dev_attrs	= coresight_dev_attrs,
+};
+
+static ssize_t coresight_show_enable(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct coresight_device *csdev = to_coresight_device(dev);
+
+	return scnprintf(buf, PAGE_SIZE, "%u\n", (unsigned)csdev->enable);
+}
+
+static ssize_t coresight_store_enable(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t size)
+{
+	int ret = 0;
+	unsigned long val;
+	struct coresight_device *csdev = to_coresight_device(dev);
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	if (val)
+		ret = coresight_enable(csdev, 0);
+	else
+		coresight_disable(csdev, 0);
+
+	if (ret)
+		return ret;
+	return size;
+}
+static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, coresight_show_enable,
+		   coresight_store_enable);
+
+static struct attribute *coresight_attrs[] = {
+	&dev_attr_enable.attr,
+	NULL,
+};
+
+static struct attribute_group coresight_attr_grp = {
+	.attrs = coresight_attrs,
+};
+
+static const struct attribute_group *coresight_attr_grps[] = {
+	&coresight_attr_grp,
+	NULL,
+};
+
+static struct device_type coresight_dev_type[CORESIGHT_DEV_TYPE_MAX] = {
+	{
+		.name = "source",
+		.groups = coresight_attr_grps,
+	},
+	{
+		.name = "link",
+	},
+	{
+		.name = "sink",
+		.groups = coresight_attr_grps,
+	},
+};
+
+static void coresight_device_release(struct device *dev)
+{
+	struct coresight_device *csdev = to_coresight_device(dev);
+	mutex_destroy(&csdev->mutex);
+	kfree(csdev);
+}
+
+static void coresight_fixup_orphan_conns(struct coresight_device *csdev)
+{
+	struct coresight_connection *conn, *temp;
+
+	mutex_lock(&coresight_conns_mutex);
+	list_for_each_entry_safe(conn, temp, &coresight_orph_conns, link) {
+		if (conn->child_id == csdev->id) {
+			conn->child_dev = csdev;
+			list_del(&conn->link);
+		}
+	}
+	mutex_unlock(&coresight_conns_mutex);
+}
+
+static void coresight_fixup_device_conns(struct coresight_device *csdev)
+{
+	int i;
+	struct coresight_device *cd;
+	bool found;
+
+	for (i = 0; i < csdev->nr_conns; i++) {
+		found = false;
+		mutex_lock(&coresight_devs_mutex);
+		list_for_each_entry(cd, &coresight_devs, link) {
+			if (csdev->conns[i].child_id == cd->id) {
+				csdev->conns[i].child_dev = cd;
+				found = true;
+				break;
+			}
+		}
+		mutex_unlock(&coresight_devs_mutex);
+		if (!found) {
+			mutex_lock(&coresight_conns_mutex);
+			list_add_tail(&csdev->conns[i].link,
+				      &coresight_orph_conns);
+			mutex_unlock(&coresight_conns_mutex);
+		}
+	}
+}
+
+struct coresight_device *coresight_register(struct coresight_desc *desc)
+{
+	int i;
+	int ret;
+	int *refcnt;
+	struct coresight_device *csdev;
+	struct coresight_connection *conns;
+
+	csdev = kzalloc(sizeof(*csdev), GFP_KERNEL);
+	if (!csdev) {
+		ret = -ENOMEM;
+		goto err_kzalloc_csdev;
+	}
+
+	mutex_init(&csdev->mutex);
+	csdev->id = desc->pdata->id;
+
+	refcnt = kzalloc(sizeof(*refcnt) * desc->pdata->nr_ports, GFP_KERNEL);
+	if (!refcnt) {
+		ret = -ENOMEM;
+		goto err_kzalloc_refcnt;
+	}
+	csdev->refcnt = refcnt;
+
+	csdev->nr_conns = desc->pdata->nr_children;
+	conns = kzalloc(sizeof(*conns) * csdev->nr_conns, GFP_KERNEL);
+	if (!conns) {
+		ret = -ENOMEM;
+		goto err_kzalloc_conns;
+	}
+	for (i = 0; i < csdev->nr_conns; i++) {
+		conns[i].child_id = desc->pdata->child_ids[i];
+		conns[i].child_port = desc->pdata->child_ports[i];
+	}
+	csdev->conns = conns;
+
+	csdev->ops = desc->ops;
+	csdev->owner = desc->owner;
+
+	csdev->dev.type = &coresight_dev_type[desc->type];
+	csdev->dev.groups = desc->groups;
+	csdev->dev.parent = desc->dev;
+	csdev->dev.bus = &coresight_bus_type;
+	csdev->dev.release = coresight_device_release;
+	dev_set_name(&csdev->dev, "%s", desc->pdata->name);
+
+	coresight_fixup_device_conns(csdev);
+	ret = device_register(&csdev->dev);
+	if (ret)
+		goto err_dev_reg;
+	coresight_fixup_orphan_conns(csdev);
+
+	mutex_lock(&coresight_devs_mutex);
+	list_add_tail(&csdev->link, &coresight_devs);
+	mutex_unlock(&coresight_devs_mutex);
+
+	return csdev;
+err_dev_reg:
+	put_device(&csdev->dev);
+	kfree(conns);
+err_kzalloc_conns:
+	kfree(refcnt);
+err_kzalloc_refcnt:
+	mutex_destroy(&csdev->mutex);
+	kfree(csdev);
+err_kzalloc_csdev:
+	return ERR_PTR(ret);
+}
+EXPORT_SYMBOL(coresight_register);
+
+void coresight_unregister(struct coresight_device *csdev)
+{
+	if (IS_ERR_OR_NULL(csdev))
+		return;
+
+	if (get_device(&csdev->dev)) {
+		mutex_lock(&csdev->mutex);
+		device_unregister(&csdev->dev);
+		mutex_unlock(&csdev->mutex);
+		put_device(&csdev->dev);
+	}
+}
+EXPORT_SYMBOL(coresight_unregister);
+
+static int __init coresight_init(void)
+{
+	return bus_register(&coresight_bus_type);
+}
+subsys_initcall(coresight_init);
+
+static void __exit coresight_exit(void)
+{
+	bus_unregister(&coresight_bus_type);
+}
+module_exit(coresight_exit);
+
+MODULE_LICENSE("GPL v2");
+/*
+ * Exclusion rules for structure fields.
+ *
+ * S: qdss.sources_mutex protected.
+ * I: qdss.sink_mutex protected.
+ * C: qdss.clk_mutex protected.
+ */
+struct qdss_ctx {
+	struct kobject			*modulekobj;
+	uint8_t				afamily;
+	struct list_head		sources;	/* S: sources list */
+	struct mutex			sources_mutex;
+	uint8_t				sink_count;	/* I: sink count */
+	struct mutex			sink_mutex;
+	uint8_t				max_clk;
+	struct clk			*clk;
+};
+
+static struct qdss_ctx qdss;
+
+/**
+ * qdss_get - get the qdss source handle
+ * @name: name of the qdss source
+ *
+ * Searches the sources list to get the qdss source handle for this source.
+ *
+ * CONTEXT:
+ * Typically called from init or probe functions
+ *
+ * RETURNS:
+ * pointer to struct qdss_source on success, %NULL on failure
+ */
+struct qdss_source *qdss_get(const char *name)
+{
+	struct qdss_source *src, *source = NULL;
+
+	mutex_lock(&qdss.sources_mutex);
+	list_for_each_entry(src, &qdss.sources, link) {
+		if (src->name) {
+			if (strncmp(src->name, name, MAX_STR_LEN))
+				continue;
+			source = src;
+			break;
+		}
+	}
+	mutex_unlock(&qdss.sources_mutex);
+
+	return source ? source : ERR_PTR(-ENOENT);
+}
+EXPORT_SYMBOL(qdss_get);
+
+/**
+ * qdss_put - release the qdss source handle
+ * @name: name of the qdss source
+ *
+ * CONTEXT:
+ * Typically called from driver remove or exit functions
+ */
+void qdss_put(struct qdss_source *src)
+{
+}
+EXPORT_SYMBOL(qdss_put);
+
+/**
+ * qdss_enable - enable qdss for the source
+ * @src: handle for the source making the call
+ *
+ * Enables qdss block (relevant funnel ports and sink) if not already
+ * enabled, otherwise increments the reference count
+ *
+ * CONTEXT:
+ * Might sleep. Uses a mutex lock. Should be called from a non-atomic context.
+ *
+ * RETURNS:
+ * 0 on success, non-zero on failure
+ */
+int qdss_enable(struct qdss_source *src)
+{
+	if (!src)
+		return -EINVAL;
+
+	if (qdss.afamily) {
+		mutex_lock(&qdss.sink_mutex);
+		if (qdss.sink_count == 0) {
+			tpiu_disable();
+			/* enable ETB first to avoid losing any trace data */
+			etb_enable();
+		}
+		qdss.sink_count++;
+		mutex_unlock(&qdss.sink_mutex);
+	}
+
+	funnel_enable(0x0, src->fport_mask);
+	return 0;
+}
+EXPORT_SYMBOL(qdss_enable);
+
+/**
+ * qdss_disable - disable qdss for the source
+ * @src: handle for the source making the call
+ *
+ * Disables qdss block (relevant funnel ports and sink) if the reference count
+ * is one, otherwise decrements the reference count
+ *
+ * CONTEXT:
+ * Might sleep. Uses a mutex lock. Should be called from a non-atomic context.
+ */
+void qdss_disable(struct qdss_source *src)
+{
+	if (!src)
+		return;
+
+	if (qdss.afamily) {
+		mutex_lock(&qdss.sink_mutex);
+		if (WARN(qdss.sink_count == 0, "qdss is unbalanced\n"))
+			goto out;
+		if (qdss.sink_count == 1) {
+			etb_dump();
+			etb_disable();
+		}
+		qdss.sink_count--;
+		mutex_unlock(&qdss.sink_mutex);
+	}
+
+	funnel_disable(0x0, src->fport_mask);
+	return;
+out:
+	mutex_unlock(&qdss.sink_mutex);
+}
+EXPORT_SYMBOL(qdss_disable);
+
+/**
+ * qdss_disable_sink - force disable the current qdss sink(s)
+ *
+ * Force disable the current qdss sink(s) to stop the sink from accepting any
+ * trace generated subsequent to this call. This function should only be used
+ * as a way to stop the sink from getting polluted with trace data that is
+ * uninteresting after an event of interest has occured.
+ *
+ * CONTEXT:
+ * Can be called from atomic or non-atomic context.
+ */
+void qdss_disable_sink(void)
+{
+	if (qdss.afamily) {
+		etb_dump();
+		etb_disable();
+	}
+}
+EXPORT_SYMBOL(qdss_disable_sink);
+
+struct kobject *qdss_get_modulekobj(void)
+{
+	return qdss.modulekobj;
+}
+
+#define QDSS_ATTR(name)						\
+static struct kobj_attribute name##_attr =				\
+		__ATTR(name, S_IRUGO | S_IWUSR, name##_show, name##_store)
+
+static ssize_t max_clk_store(struct kobject *kobj,
+			struct kobj_attribute *attr,
+			const char *buf, size_t n)
+{
+	unsigned long val;
+
+	if (sscanf(buf, "%lx", &val) != 1)
+		return -EINVAL;
+
+	qdss.max_clk = val;
+	return n;
+}
+static ssize_t max_clk_show(struct kobject *kobj,
+			struct kobj_attribute *attr,
+			char *buf)
+{
+	unsigned long val = qdss.max_clk;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+QDSS_ATTR(max_clk);
+
+static void __devinit qdss_add_sources(struct qdss_source *srcs, size_t num)
+{
+	mutex_lock(&qdss.sources_mutex);
+	while (num--) {
+		list_add_tail(&srcs->link, &qdss.sources);
+		srcs++;
+	}
+	mutex_unlock(&qdss.sources_mutex);
+}
+
+static int __init qdss_sysfs_init(void)
+{
+	int ret;
+
+	qdss.modulekobj = kset_find_obj(module_kset, KBUILD_MODNAME);
+	if (!qdss.modulekobj) {
+		pr_err("failed to find QDSS sysfs module kobject\n");
+		ret = -ENOENT;
+		goto err;
+	}
+
+	ret = sysfs_create_file(qdss.modulekobj, &max_clk_attr.attr);
+	if (ret) {
+		pr_err("failed to create QDSS sysfs max_clk attribute\n");
+		goto err;
+	}
+
+	return 0;
+err:
+	return ret;
+}
+
+static void __devexit qdss_sysfs_exit(void)
+{
+	sysfs_remove_file(qdss.modulekobj, &max_clk_attr.attr);
+}
+
+static int __devinit qdss_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct msm_qdss_platform_data *pdata;
+
+	mutex_init(&qdss.sources_mutex);
+	mutex_init(&qdss.sink_mutex);
+
+	INIT_LIST_HEAD(&qdss.sources);
+
+	pdata = pdev->dev.platform_data;
+	if (!pdata)
+		goto err_pdata;
+
+	qdss.afamily = pdata->afamily;
+	qdss_add_sources(pdata->src_table, pdata->size);
+
+	pr_info("QDSS arch initialized\n");
+	return 0;
+err_pdata:
+	mutex_destroy(&qdss.sink_mutex);
+	mutex_destroy(&qdss.sources_mutex);
+	pr_err("QDSS init failed\n");
+	return ret;
+}
+
+static int __devexit qdss_remove(struct platform_device *pdev)
+{
+	qdss_sysfs_exit();
+	mutex_destroy(&qdss.sink_mutex);
+	mutex_destroy(&qdss.sources_mutex);
+
+	return 0;
+}
+
+static struct of_device_id qdss_match[] = {
+	{.compatible = "qcom,msm-qdss"},
+	{}
+};
+
+static struct platform_driver qdss_driver = {
+	.probe          = qdss_probe,
+	.remove         = __devexit_p(qdss_remove),
+	.driver         = {
+		.name   = "msm_qdss",
+		.owner	= THIS_MODULE,
+		.of_match_table = qdss_match,
+	},
+};
+
+static int __init qdss_init(void)
+{
+	return platform_driver_register(&qdss_driver);
+}
+arch_initcall(qdss_init);
+
+static int __init qdss_module_init(void)
+{
+	int ret;
+
+	ret = qdss_sysfs_init();
+	if (ret)
+		goto err_sysfs;
+
+	pr_info("QDSS module initialized\n");
+	return 0;
+err_sysfs:
+	return ret;
+}
+module_init(qdss_module_init);
+
+static void __exit qdss_exit(void)
+{
+	platform_driver_unregister(&qdss_driver);
+}
+module_exit(qdss_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Qualcomm Debug SubSystem Driver");
diff --git a/drivers/gpu/msm/kgsl_drm.c b/drivers/gpu/msm/kgsl_drm.c
index 66ac08f..870a7d7 100644
--- a/drivers/gpu/msm/kgsl_drm.c
+++ b/drivers/gpu/msm/kgsl_drm.c
@@ -238,11 +238,8 @@
 	}
 
 	if (TYPE_IS_PMEM(priv->type)) {
-		int type;
-
 		if (priv->type == DRM_KGSL_GEM_TYPE_EBI ||
 		    priv->type & DRM_KGSL_GEM_PMEM_EBI) {
-				type = PMEM_MEMTYPE_EBI1;
 				result = kgsl_sharedmem_ebimem_user(
 						&priv->memdesc,
 						priv->pagetable,
diff --git a/drivers/media/radio/radio-tavarua.c b/drivers/media/radio/radio-tavarua.c
index a2993ce..116b7f9 100644
--- a/drivers/media/radio/radio-tavarua.c
+++ b/drivers/media/radio/radio-tavarua.c
@@ -3453,9 +3453,17 @@
 		if (retval < 0)
 			FMDBG("write failed");
 	} break;
+	case V4L2_CID_PRIVATE_SOFT_MUTE:
+		radio->registers[IOCTRL] &= ~(IOC_SFT_MUTE);
+		if (ctrl->value)
+			radio->registers[IOCTRL] |= IOC_SFT_MUTE;
+		retval = tavarua_write_register(radio, IOCTRL,
+					radio->registers[IOCTRL]);
+		if (retval < 0)
+			FMDERR("Failed to enable/disable SMute\n");
+		break;
 	/*These IOCTL's are place holders to keep the
 	driver compatible with change in frame works for IRIS */
-	case V4L2_CID_PRIVATE_SOFT_MUTE:
 	case V4L2_CID_PRIVATE_RIVA_ACCS_ADDR:
 	case V4L2_CID_PRIVATE_RIVA_ACCS_LEN:
 	case V4L2_CID_PRIVATE_RIVA_PEEK:
diff --git a/drivers/media/video/msm/Kconfig b/drivers/media/video/msm/Kconfig
index 5ffc133..9c791e4 100644
--- a/drivers/media/video/msm/Kconfig
+++ b/drivers/media/video/msm/Kconfig
@@ -271,6 +271,15 @@
 	cores and composite them into a single
 	interrupt to the MSM.
 
+config MSM_CPP
+        bool "Qualcomm MSM Camera Post Processing Engine support"
+        depends on MSM_CAMERA && MSM_CAMERA_V4L2
+        ---help---
+          Enable support for Camera Post-processing Engine
+          The Post processing engine is capable of scaling
+          and cropping image. The driver support V4L2 subdev
+          APIs.
+
 config QUP_EXCLUSIVE_TO_CAMERA
 	bool "QUP exclusive to camera"
 	depends on MSM_CAMERA
diff --git a/drivers/media/video/msm/Makefile b/drivers/media/video/msm/Makefile
index 431da2e..63120da 100644
--- a/drivers/media/video/msm/Makefile
+++ b/drivers/media/video/msm/Makefile
@@ -13,6 +13,7 @@
   EXTRA_CFLAGS += -Idrivers/media/video/msm/server
   obj-$(CONFIG_MSM_CAMERA) += msm_isp.o msm.o msm_mem.o msm_mctl.o msm_mctl_buf.o msm_mctl_pp.o
   obj-$(CONFIG_MSM_CAMERA) += server/ eeprom/ sensors/ actuators/ csi/
+  obj-$(CONFIG_MSM_CPP) += cpp/
   obj-$(CONFIG_MSM_CAMERA) += msm_gesture.o
   obj-$(CONFIG_MSM_CAM_IRQ_ROUTER) += msm_camirq_router.o
 else
diff --git a/drivers/media/video/msm/actuators/msm_actuator.c b/drivers/media/video/msm/actuators/msm_actuator.c
index 774a46d..554cddc 100644
--- a/drivers/media/video/msm/actuators/msm_actuator.c
+++ b/drivers/media/video/msm/actuators/msm_actuator.c
@@ -14,55 +14,42 @@
 #include "msm_actuator.h"
 
 static struct msm_actuator_ctrl_t msm_actuator_t;
-
-static struct msm_actuator msm_vcm_actuator_table = {
-	.act_type = ACTUATOR_VCM,
-	.func_tbl = {
-		.actuator_init_step_table = msm_actuator_init_step_table,
-		.actuator_move_focus = msm_actuator_move_focus,
-		.actuator_write_focus = msm_actuator_write_focus,
-		.actuator_set_default_focus = msm_actuator_set_default_focus,
-		.actuator_init_focus = msm_actuator_init_focus,
-		.actuator_i2c_write = msm_actuator_i2c_write,
-	},
-};
-
-static struct msm_actuator msm_piezo_actuator_table = {
-	.act_type = ACTUATOR_PIEZO,
-	.func_tbl = {
-		.actuator_init_step_table = NULL,
-		.actuator_move_focus = msm_actuator_piezo_move_focus,
-		.actuator_write_focus = NULL,
-		.actuator_set_default_focus =
-			msm_actuator_piezo_set_default_focus,
-		.actuator_init_focus = msm_actuator_init_focus,
-		.actuator_i2c_write = msm_actuator_i2c_write,
-	},
-};
+static struct msm_actuator msm_vcm_actuator_table;
+static struct msm_actuator msm_piezo_actuator_table;
 
 static struct msm_actuator *actuators[] = {
 	&msm_vcm_actuator_table,
 	&msm_piezo_actuator_table,
 };
 
-int32_t msm_actuator_piezo_set_default_focus(
+static int32_t msm_actuator_piezo_set_default_focus(
 	struct msm_actuator_ctrl_t *a_ctrl,
 	struct msm_actuator_move_params_t *move_params)
 {
 	int32_t rc = 0;
 
 	if (a_ctrl->curr_step_pos != 0) {
-		rc = a_ctrl->func_tbl->actuator_i2c_write(a_ctrl,
-			a_ctrl->initial_code, 0);
-		rc = a_ctrl->func_tbl->actuator_i2c_write(a_ctrl,
-			a_ctrl->initial_code, 0);
+		a_ctrl->i2c_tbl_index = 0;
+		rc = a_ctrl->func_tbl->actuator_parse_i2c_params(a_ctrl,
+			a_ctrl->initial_code, 0, 0);
+		rc = a_ctrl->func_tbl->actuator_parse_i2c_params(a_ctrl,
+			a_ctrl->initial_code, 0, 0);
+		rc = msm_camera_i2c_write_table_w_microdelay(
+			&a_ctrl->i2c_client, a_ctrl->i2c_reg_tbl,
+			a_ctrl->i2c_tbl_index, a_ctrl->i2c_data_type);
+		if (rc < 0) {
+			pr_err("%s: i2c write error:%d\n",
+				__func__, rc);
+			return rc;
+		}
+		a_ctrl->i2c_tbl_index = 0;
 		a_ctrl->curr_step_pos = 0;
 	}
 	return rc;
 }
 
-int32_t msm_actuator_i2c_write(struct msm_actuator_ctrl_t *a_ctrl,
-	int16_t next_lens_position, uint32_t hw_params)
+static int32_t msm_actuator_parse_i2c_params(struct msm_actuator_ctrl_t *a_ctrl,
+	int16_t next_lens_position, uint32_t hw_params, uint16_t delay)
 {
 	struct msm_actuator_reg_params_t *write_arr = a_ctrl->reg_tbl;
 	uint32_t hw_dword = hw_params;
@@ -70,6 +57,7 @@
 	uint16_t value = 0;
 	uint32_t size = a_ctrl->reg_tbl_size, i = 0;
 	int32_t rc = 0;
+	struct msm_camera_i2c_reg_tbl *i2c_tbl = a_ctrl->i2c_reg_tbl;
 	CDBG("%s: IN\n", __func__);
 	for (i = 0; i < size; i++) {
 		if (write_arr[i].reg_write_type == MSM_ACTUATOR_WRITE_DAC) {
@@ -85,16 +73,13 @@
 					i2c_byte2 = value & 0xFF;
 					CDBG("%s: byte1:0x%x, byte2:0x%x\n",
 					__func__, i2c_byte1, i2c_byte2);
-					rc = msm_camera_i2c_write(
-						&a_ctrl->i2c_client,
-						i2c_byte1, i2c_byte2,
-						a_ctrl->i2c_data_type);
-					if (rc < 0) {
-						pr_err("%s: i2c write error:%d\n",
-							__func__, rc);
-						return rc;
-					}
-
+					i2c_tbl[a_ctrl->i2c_tbl_index].
+						reg_addr = i2c_byte1;
+					i2c_tbl[a_ctrl->i2c_tbl_index].
+						reg_data = i2c_byte2;
+					i2c_tbl[a_ctrl->i2c_tbl_index].
+						delay = 0;
+					a_ctrl->i2c_tbl_index++;
 					i++;
 					i2c_byte1 = write_arr[i].reg_addr;
 					i2c_byte2 = (value & 0xFF00) >> 8;
@@ -110,14 +95,16 @@
 		}
 		CDBG("%s: i2c_byte1:0x%x, i2c_byte2:0x%x\n", __func__,
 			i2c_byte1, i2c_byte2);
-		rc = msm_camera_i2c_write(&a_ctrl->i2c_client,
-			i2c_byte1, i2c_byte2, a_ctrl->i2c_data_type);
+		i2c_tbl[a_ctrl->i2c_tbl_index].reg_addr = i2c_byte1;
+		i2c_tbl[a_ctrl->i2c_tbl_index].reg_data = i2c_byte2;
+		i2c_tbl[a_ctrl->i2c_tbl_index].delay = delay;
+		a_ctrl->i2c_tbl_index++;
 	}
 		CDBG("%s: OUT\n", __func__);
 	return rc;
 }
 
-int32_t msm_actuator_init_focus(struct msm_actuator_ctrl_t *a_ctrl,
+static int32_t msm_actuator_init_focus(struct msm_actuator_ctrl_t *a_ctrl,
 	uint16_t size, enum msm_actuator_data_type type,
 	struct reg_settings_t *settings)
 {
@@ -153,7 +140,7 @@
 	return rc;
 }
 
-int32_t msm_actuator_write_focus(
+static int32_t msm_actuator_write_focus(
 	struct msm_actuator_ctrl_t *a_ctrl,
 	uint16_t curr_lens_pos,
 	struct damping_params_t *damping_params,
@@ -177,27 +164,25 @@
 			(next_lens_pos +
 				(sign_direction * damping_code_step))) {
 		rc = a_ctrl->func_tbl->
-			actuator_i2c_write(a_ctrl, next_lens_pos,
-				damping_params->hw_params);
+			actuator_parse_i2c_params(a_ctrl, next_lens_pos,
+				damping_params->hw_params, wait_time);
 		if (rc < 0) {
 			pr_err("%s: error:%d\n",
 				__func__, rc);
 			return rc;
 		}
 		curr_lens_pos = next_lens_pos;
-		usleep(wait_time);
 	}
 
 	if (curr_lens_pos != code_boundary) {
 		rc = a_ctrl->func_tbl->
-			actuator_i2c_write(a_ctrl, code_boundary,
-				damping_params->hw_params);
-		usleep(wait_time);
+			actuator_parse_i2c_params(a_ctrl, code_boundary,
+				damping_params->hw_params, wait_time);
 	}
 	return rc;
 }
 
-int32_t msm_actuator_piezo_move_focus(
+static int32_t msm_actuator_piezo_move_focus(
 	struct msm_actuator_ctrl_t *a_ctrl,
 	struct msm_actuator_move_params_t *move_params)
 {
@@ -208,17 +193,27 @@
 	if (num_steps == 0)
 		return rc;
 
+	a_ctrl->i2c_tbl_index = 0;
 	rc = a_ctrl->func_tbl->
-		actuator_i2c_write(a_ctrl,
+		actuator_parse_i2c_params(a_ctrl,
 		(num_steps *
 		a_ctrl->region_params[0].code_per_step),
-		move_params->ringing_params[0].hw_params);
+		move_params->ringing_params[0].hw_params, 0);
 
+	rc = msm_camera_i2c_write_table_w_microdelay(&a_ctrl->i2c_client,
+		a_ctrl->i2c_reg_tbl, a_ctrl->i2c_tbl_index,
+		a_ctrl->i2c_data_type);
+	if (rc < 0) {
+		pr_err("%s: i2c write error:%d\n",
+			__func__, rc);
+		return rc;
+	}
+	a_ctrl->i2c_tbl_index = 0;
 	a_ctrl->curr_step_pos = dest_step_position;
 	return rc;
 }
 
-int32_t msm_actuator_move_focus(
+static int32_t msm_actuator_move_focus(
 	struct msm_actuator_ctrl_t *a_ctrl,
 	struct msm_actuator_move_params_t *move_params)
 {
@@ -241,6 +236,7 @@
 		return rc;
 
 	curr_lens_pos = a_ctrl->step_position_table[a_ctrl->curr_step_pos];
+	a_ctrl->i2c_tbl_index = 0;
 	CDBG("curr_step_pos =%d dest_step_pos =%d curr_lens_pos=%d\n",
 		a_ctrl->curr_step_pos, dest_step_pos, curr_lens_pos);
 
@@ -299,10 +295,20 @@
 		a_ctrl->curr_step_pos = target_step_pos;
 	}
 
+	rc = msm_camera_i2c_write_table_w_microdelay(&a_ctrl->i2c_client,
+		a_ctrl->i2c_reg_tbl, a_ctrl->i2c_tbl_index,
+		a_ctrl->i2c_data_type);
+	if (rc < 0) {
+		pr_err("%s: i2c write error:%d\n",
+			__func__, rc);
+		return rc;
+	}
+	a_ctrl->i2c_tbl_index = 0;
+
 	return rc;
 }
 
-int32_t msm_actuator_init_step_table(struct msm_actuator_ctrl_t *a_ctrl,
+static int32_t msm_actuator_init_step_table(struct msm_actuator_ctrl_t *a_ctrl,
 	struct msm_actuator_set_info_t *set_info)
 {
 	int16_t code_per_step = 0;
@@ -361,7 +367,7 @@
 	return rc;
 }
 
-int32_t msm_actuator_set_default_focus(
+static int32_t msm_actuator_set_default_focus(
 	struct msm_actuator_ctrl_t *a_ctrl,
 	struct msm_actuator_move_params_t *move_params)
 {
@@ -373,7 +379,7 @@
 	return rc;
 }
 
-int32_t msm_actuator_power_down(struct msm_actuator_ctrl_t *a_ctrl)
+static int32_t msm_actuator_power_down(struct msm_actuator_ctrl_t *a_ctrl)
 {
 	int32_t rc = 0;
 	if (a_ctrl->vcm_enable) {
@@ -384,10 +390,13 @@
 
 	kfree(a_ctrl->step_position_table);
 	a_ctrl->step_position_table = NULL;
+	kfree(a_ctrl->i2c_reg_tbl);
+	a_ctrl->i2c_reg_tbl = NULL;
+	a_ctrl->i2c_tbl_index = 0;
 	return rc;
 }
 
-int32_t msm_actuator_init(struct msm_actuator_ctrl_t *a_ctrl,
+static int32_t msm_actuator_init(struct msm_actuator_ctrl_t *a_ctrl,
 	struct msm_actuator_set_info_t *set_info) {
 	struct reg_settings_t *init_settings = NULL;
 	int32_t rc = -EFAULT;
@@ -412,7 +421,6 @@
 		pr_err("%s: MAX_ACTUATOR_REGION is exceeded.\n", __func__);
 		return -EFAULT;
 	}
-	a_ctrl->total_steps = set_info->af_tuning_params.total_steps;
 	a_ctrl->pwd_step = set_info->af_tuning_params.pwd_step;
 	a_ctrl->total_steps = set_info->af_tuning_params.total_steps;
 
@@ -430,11 +438,22 @@
 			__func__);
 		return -EFAULT;
 	}
+
+	a_ctrl->i2c_reg_tbl =
+		kmalloc(sizeof(struct msm_camera_i2c_reg_tbl) *
+		(set_info->af_tuning_params.total_steps + 1), GFP_KERNEL);
+	if (!a_ctrl->i2c_reg_tbl) {
+		pr_err("%s kmalloc fail\n", __func__);
+		return -EFAULT;
+	}
+
 	if (copy_from_user(&a_ctrl->reg_tbl,
 		(void *)set_info->actuator_params.reg_tbl_params,
 		a_ctrl->reg_tbl_size *
-		sizeof(struct msm_actuator_reg_params_t)))
+		sizeof(struct msm_actuator_reg_params_t))) {
+		kfree(a_ctrl->i2c_reg_tbl);
 		return -EFAULT;
+	}
 
 	if (set_info->actuator_params.init_setting_size) {
 		if (a_ctrl->func_tbl->actuator_init_focus) {
@@ -442,6 +461,7 @@
 				(set_info->actuator_params.init_setting_size),
 				GFP_KERNEL);
 			if (init_settings == NULL) {
+				kfree(a_ctrl->i2c_reg_tbl);
 				pr_err("%s Error allocating memory for init_settings\n",
 					__func__);
 				return -EFAULT;
@@ -451,6 +471,7 @@
 				set_info->actuator_params.init_setting_size *
 				sizeof(struct reg_settings_t))) {
 				kfree(init_settings);
+				kfree(a_ctrl->i2c_reg_tbl);
 				pr_err("%s Error copying init_settings\n",
 					__func__);
 				return -EFAULT;
@@ -461,6 +482,7 @@
 				init_settings);
 			kfree(init_settings);
 			if (rc < 0) {
+				kfree(a_ctrl->i2c_reg_tbl);
 				pr_err("%s Error actuator_init_focus\n",
 					__func__);
 				return -EFAULT;
@@ -480,7 +502,7 @@
 }
 
 
-int32_t msm_actuator_config(struct msm_actuator_ctrl_t *a_ctrl,
+static int32_t msm_actuator_config(struct msm_actuator_ctrl_t *a_ctrl,
 							void __user *argp)
 {
 	struct msm_actuator_cfg_data cdata;
@@ -519,7 +541,7 @@
 	return rc;
 }
 
-int32_t msm_actuator_i2c_probe(
+static int32_t msm_actuator_i2c_probe(
 	struct i2c_client *client,
 	const struct i2c_device_id *id)
 {
@@ -554,7 +576,7 @@
 	return rc;
 }
 
-int32_t msm_actuator_power_up(struct msm_actuator_ctrl_t *a_ctrl)
+static int32_t msm_actuator_power_up(struct msm_actuator_ctrl_t *a_ctrl)
 {
 	int rc = 0;
 	CDBG("%s called\n", __func__);
@@ -594,7 +616,7 @@
 	return i2c_add_driver(msm_actuator_t.i2c_driver);
 }
 
-long msm_actuator_subdev_ioctl(struct v4l2_subdev *sd,
+static long msm_actuator_subdev_ioctl(struct v4l2_subdev *sd,
 			unsigned int cmd, void *arg)
 {
 	struct msm_actuator_ctrl_t *a_ctrl = get_actrl(sd);
@@ -607,7 +629,7 @@
 	}
 }
 
-int32_t msm_actuator_power(struct v4l2_subdev *sd, int on)
+static int32_t msm_actuator_power(struct v4l2_subdev *sd, int on)
 {
 	int rc = 0;
 	struct msm_actuator_ctrl_t *a_ctrl = get_actrl(sd);
@@ -644,6 +666,31 @@
 
 };
 
+static struct msm_actuator msm_vcm_actuator_table = {
+	.act_type = ACTUATOR_VCM,
+	.func_tbl = {
+		.actuator_init_step_table = msm_actuator_init_step_table,
+		.actuator_move_focus = msm_actuator_move_focus,
+		.actuator_write_focus = msm_actuator_write_focus,
+		.actuator_set_default_focus = msm_actuator_set_default_focus,
+		.actuator_init_focus = msm_actuator_init_focus,
+		.actuator_parse_i2c_params = msm_actuator_parse_i2c_params,
+	},
+};
+
+static struct msm_actuator msm_piezo_actuator_table = {
+	.act_type = ACTUATOR_PIEZO,
+	.func_tbl = {
+		.actuator_init_step_table = NULL,
+		.actuator_move_focus = msm_actuator_piezo_move_focus,
+		.actuator_write_focus = NULL,
+		.actuator_set_default_focus =
+			msm_actuator_piezo_set_default_focus,
+		.actuator_init_focus = msm_actuator_init_focus,
+		.actuator_parse_i2c_params = msm_actuator_parse_i2c_params,
+	},
+};
+
 subsys_initcall(msm_actuator_i2c_add_driver);
 MODULE_DESCRIPTION("MSM ACTUATOR");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/actuators/msm_actuator.h b/drivers/media/video/msm/actuators/msm_actuator.h
index 4f936e7..82157e8 100644
--- a/drivers/media/video/msm/actuators/msm_actuator.h
+++ b/drivers/media/video/msm/actuators/msm_actuator.h
@@ -51,8 +51,8 @@
 			struct msm_actuator_move_params_t *);
 	int32_t (*actuator_move_focus) (struct msm_actuator_ctrl_t *,
 			struct msm_actuator_move_params_t *);
-	int32_t (*actuator_i2c_write)(struct msm_actuator_ctrl_t *,
-			int16_t, uint32_t);
+	int32_t (*actuator_parse_i2c_params)(struct msm_actuator_ctrl_t *,
+			int16_t, uint32_t, uint16_t);
 	int32_t (*actuator_write_focus)(struct msm_actuator_ctrl_t *,
 			uint16_t,
 			struct damping_params_t *,
@@ -87,40 +87,11 @@
 	uint32_t total_steps;
 	uint16_t pwd_step;
 	uint16_t initial_code;
+	struct msm_camera_i2c_reg_tbl *i2c_reg_tbl;
+	uint16_t i2c_tbl_index;
 };
 
 struct msm_actuator_ctrl_t *get_actrl(struct v4l2_subdev *sd);
-int32_t msm_actuator_i2c_write(struct msm_actuator_ctrl_t *a_ctrl,
-		int16_t next_lens_position, uint32_t hw_params);
-int32_t msm_actuator_init_focus(struct msm_actuator_ctrl_t *a_ctrl,
-		uint16_t size, enum msm_actuator_data_type type,
-		struct reg_settings_t *settings);
-int32_t msm_actuator_i2c_write_b_af(struct msm_actuator_ctrl_t *a_ctrl,
-		uint8_t msb,
-		uint8_t lsb);
-int32_t msm_actuator_move_focus(struct msm_actuator_ctrl_t *a_ctrl,
-		struct msm_actuator_move_params_t *move_params);
-int32_t msm_actuator_piezo_move_focus(
-		struct msm_actuator_ctrl_t *a_ctrl,
-		struct msm_actuator_move_params_t *move_params);
-int32_t msm_actuator_init_step_table(struct msm_actuator_ctrl_t *a_ctrl,
-		struct msm_actuator_set_info_t *set_info);
-int32_t msm_actuator_set_default_focus(struct msm_actuator_ctrl_t *a_ctrl,
-		struct msm_actuator_move_params_t *move_params);
-int32_t msm_actuator_piezo_set_default_focus(
-		struct msm_actuator_ctrl_t *a_ctrl,
-		struct msm_actuator_move_params_t *move_params);
-int32_t msm_actuator_i2c_probe(struct i2c_client *client,
-		const struct i2c_device_id *id);
-int32_t msm_actuator_write_focus(struct msm_actuator_ctrl_t *a_ctrl,
-		uint16_t curr_lens_pos, struct damping_params_t *damping_params,
-		int8_t sign_direction, int16_t code_boundary);
-int32_t msm_actuator_write_focus2(struct msm_actuator_ctrl_t *a_ctrl,
-		uint16_t curr_lens_pos, struct damping_params_t *damping_params,
-		int8_t sign_direction, int16_t code_boundary);
-long msm_actuator_subdev_ioctl(struct v4l2_subdev *sd,
-			unsigned int cmd, void *arg);
-int32_t msm_actuator_power(struct v4l2_subdev *sd, int on);
 
 #define VIDIOC_MSM_ACTUATOR_CFG \
 	_IOWR('V', BASE_VIDIOC_PRIVATE + 11, void __user *)
diff --git a/drivers/media/video/msm/cpp/Makefile b/drivers/media/video/msm/cpp/Makefile
new file mode 100644
index 0000000..b4f1fdf
--- /dev/null
+++ b/drivers/media/video/msm/cpp/Makefile
@@ -0,0 +1,5 @@
+GCC_VERSION      := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
+ccflags-y += -Idrivers/media/video/msm
+ccflags-y += -Idrivers/media/video/msm/io
+obj-$(CONFIG_MSM_CPP) += msm_cpp.o
+
diff --git a/drivers/media/video/msm/cpp/msm_cpp.c b/drivers/media/video/msm/cpp/msm_cpp.c
new file mode 100644
index 0000000..e569388
--- /dev/null
+++ b/drivers/media/video/msm/cpp/msm_cpp.c
@@ -0,0 +1,412 @@
+/* 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/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <mach/board.h>
+#include <mach/camera.h>
+#include <mach/vreg.h>
+#include <media/msm_isp.h>
+#include <linux/proc_fs.h>
+#include <linux/debugfs.h>
+
+#include "msm_cpp.h"
+#include "msm.h"
+
+#define CONFIG_MSM_CPP_DBG 0
+
+#if CONFIG_MSM_CPP_DBG
+#define CPP_DBG(fmt, args...) pr_info(fmt, ##args)
+#else
+#define CPP_DBG(fmt, args...) pr_debug(fmt, ##args)
+#endif
+
+static int cpp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	uint32_t i;
+	struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
+	CPP_DBG("%s\n", __func__);
+
+	mutex_lock(&cpp_dev->mutex);
+	if (cpp_dev->cpp_open_cnt == MAX_ACTIVE_CPP_INSTANCE) {
+		pr_err("No free CPP instance\n");
+		mutex_unlock(&cpp_dev->mutex);
+		return -ENODEV;
+	}
+
+	for (i = 0; i < MAX_ACTIVE_CPP_INSTANCE; i++) {
+		if (cpp_dev->cpp_subscribe_list[i].active == 0) {
+			cpp_dev->cpp_subscribe_list[i].active = 1;
+			cpp_dev->cpp_subscribe_list[i].vfh = &fh->vfh;
+			break;
+		}
+	}
+	if (i == MAX_ACTIVE_CPP_INSTANCE) {
+		pr_err("No free instance\n");
+		mutex_unlock(&cpp_dev->mutex);
+		return -ENODEV;
+	}
+
+	CPP_DBG("open %d %p\n", i, &fh->vfh);
+	cpp_dev->cpp_open_cnt++;
+	mutex_unlock(&cpp_dev->mutex);
+	return 0;
+}
+
+static int cpp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	uint32_t i;
+	struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
+	mutex_lock(&cpp_dev->mutex);
+	for (i = 0; i < MAX_ACTIVE_CPP_INSTANCE; i++) {
+		if (cpp_dev->cpp_subscribe_list[i].vfh == &fh->vfh) {
+			cpp_dev->cpp_subscribe_list[i].active = 0;
+			cpp_dev->cpp_subscribe_list[i].vfh = NULL;
+			break;
+		}
+	}
+	if (i == MAX_ACTIVE_CPP_INSTANCE) {
+		pr_err("Invalid close\n");
+		mutex_unlock(&cpp_dev->mutex);
+		return -ENODEV;
+	}
+
+	CPP_DBG("close %d %p\n", i, &fh->vfh);
+	cpp_dev->cpp_open_cnt--;
+	mutex_unlock(&cpp_dev->mutex);
+	return 0;
+}
+
+static const struct v4l2_subdev_internal_ops msm_cpp_internal_ops = {
+	.open = cpp_open_node,
+	.close = cpp_close_node,
+};
+
+static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev)
+{
+	struct v4l2_event v4l2_evt;
+	struct msm_queue_cmd *frame_qcmd;
+	struct msm_queue_cmd *event_qcmd;
+	struct msm_cpp_frame_info_t *processed_frame;
+	struct msm_device_queue *queue = &cpp_dev->processing_q;
+
+	if (queue->len > 0) {
+		frame_qcmd = msm_dequeue(queue, list_frame);
+		processed_frame = frame_qcmd->command;
+
+		event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
+		if (!event_qcmd) {
+			pr_err("%s Insufficient memory. return", __func__);
+			return -ENOMEM;
+		}
+		atomic_set(&event_qcmd->on_heap, 1);
+		event_qcmd->command = processed_frame;
+		CPP_DBG("fid %d\n", processed_frame->frame_id);
+		msm_enqueue(&cpp_dev->eventData_q, &event_qcmd->list_eventdata);
+
+		v4l2_evt.id = processed_frame->inst_id;
+		v4l2_evt.type = V4L2_EVENT_CPP_FRAME_DONE;
+		v4l2_event_queue(cpp_dev->subdev.devnode, &v4l2_evt);
+	}
+	return 0;
+}
+
+static int msm_cpp_send_frame_to_hardware(struct cpp_device *cpp_dev)
+{
+	struct msm_queue_cmd *frame_qcmd;
+	struct msm_cpp_frame_info_t *process_frame;
+	struct msm_device_queue *queue;
+
+	if (cpp_dev->processing_q.len < MAX_CPP_PROCESSING_FRAME) {
+		while (cpp_dev->processing_q.len < MAX_CPP_PROCESSING_FRAME) {
+			if (cpp_dev->realtime_q.len != 0) {
+				queue = &cpp_dev->realtime_q;
+			} else if (cpp_dev->offline_q.len != 0) {
+				queue = &cpp_dev->offline_q;
+			} else {
+				pr_debug("%s: All frames queued\n", __func__);
+				break;
+			}
+			frame_qcmd = msm_dequeue(queue, list_frame);
+			/*TBD Code to actually sending to harware*/
+			process_frame = frame_qcmd->command;
+
+			msm_enqueue(&cpp_dev->processing_q,
+						&frame_qcmd->list_frame);
+		}
+	}
+	return 0;
+}
+
+long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int cmd, void *arg)
+{
+	struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
+	struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
+	int rc = 0;
+
+	CPP_DBG("%s: %d\n", __func__, __LINE__);
+	mutex_lock(&cpp_dev->mutex);
+	CPP_DBG("%s cmd: %d\n", __func__, cmd);
+	switch (cmd) {
+	case VIDIOC_MSM_CPP_CFG: {
+		struct msm_queue_cmd *frame_qcmd;
+		struct msm_cpp_frame_info_t *new_frame =
+			kzalloc(sizeof(struct msm_cpp_frame_info_t),
+					GFP_KERNEL);
+		if (!new_frame) {
+			pr_err("%s Insufficient memory. return", __func__);
+			mutex_unlock(&cpp_dev->mutex);
+			return -ENOMEM;
+		}
+
+		COPY_FROM_USER(rc, new_frame,
+			       (void __user *)ioctl_ptr->ioctl_ptr,
+			       sizeof(struct msm_cpp_frame_info_t));
+		if (rc) {
+			ERR_COPY_FROM_USER();
+			kfree(new_frame);
+			mutex_unlock(&cpp_dev->mutex);
+			return -EINVAL;
+		}
+
+		frame_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
+		if (!frame_qcmd) {
+			pr_err("%s Insufficient memory. return", __func__);
+			kfree(new_frame);
+			mutex_unlock(&cpp_dev->mutex);
+			return -ENOMEM;
+		}
+
+		atomic_set(&frame_qcmd->on_heap, 1);
+		frame_qcmd->command = new_frame;
+		if (new_frame->frame_type == MSM_CPP_REALTIME_FRAME) {
+			msm_enqueue(&cpp_dev->realtime_q,
+						&frame_qcmd->list_frame);
+		} else if (new_frame->frame_type == MSM_CPP_OFFLINE_FRAME) {
+			msm_enqueue(&cpp_dev->offline_q,
+						&frame_qcmd->list_frame);
+		} else {
+			pr_err("%s: Invalid frame type\n", __func__);
+			kfree(new_frame);
+			kfree(frame_qcmd);
+			mutex_unlock(&cpp_dev->mutex);
+			return -EINVAL;
+		}
+		break;
+	}
+	case VIDIOC_MSM_CPP_GET_EVENTPAYLOAD: {
+		struct msm_device_queue *queue = &cpp_dev->eventData_q;
+		struct msm_queue_cmd *event_qcmd;
+		struct msm_cpp_frame_info_t *process_frame;
+		event_qcmd = msm_dequeue(queue, list_eventdata);
+		process_frame = event_qcmd->command;
+		CPP_DBG("fid %d\n", process_frame->frame_id);
+		if (copy_to_user((void __user *)ioctl_ptr->ioctl_ptr,
+				process_frame,
+				sizeof(struct msm_cpp_frame_info_t))) {
+					mutex_unlock(&cpp_dev->mutex);
+					return -EINVAL;
+		}
+		kfree(process_frame);
+		kfree(event_qcmd);
+		break;
+	}
+	}
+	mutex_unlock(&cpp_dev->mutex);
+	CPP_DBG("%s: %d\n", __func__, __LINE__);
+	return 0;
+}
+
+int msm_cpp_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+	struct v4l2_event_subscription *sub)
+{
+	CPP_DBG("%s\n", __func__);
+	return v4l2_event_subscribe(fh, sub, MAX_CPP_V4l2_EVENTS);
+}
+
+int msm_cpp_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
+	struct v4l2_event_subscription *sub)
+{
+	CPP_DBG("%s\n", __func__);
+	return v4l2_event_unsubscribe(fh, sub);
+}
+
+static struct v4l2_subdev_core_ops msm_cpp_subdev_core_ops = {
+	.ioctl = msm_cpp_subdev_ioctl,
+	.subscribe_event = msm_cpp_subscribe_event,
+	.unsubscribe_event = msm_cpp_unsubscribe_event,
+};
+
+static const struct v4l2_subdev_ops msm_cpp_subdev_ops = {
+	.core = &msm_cpp_subdev_core_ops,
+};
+
+static int msm_cpp_enable_debugfs(struct cpp_device *cpp_dev);
+
+static struct v4l2_file_operations msm_cpp_v4l2_subdev_fops;
+
+static long msm_cpp_subdev_do_ioctl(
+	struct file *file, unsigned int cmd, void *arg)
+{
+	struct video_device *vdev = video_devdata(file);
+	struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
+	struct v4l2_fh *vfh = file->private_data;
+
+	switch (cmd) {
+	case VIDIOC_DQEVENT:
+		if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS))
+			return -ENOIOCTLCMD;
+
+		return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK);
+
+	case VIDIOC_SUBSCRIBE_EVENT:
+		return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg);
+
+	case VIDIOC_UNSUBSCRIBE_EVENT:
+		return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg);
+
+	case VIDIOC_MSM_CPP_GET_INST_INFO: {
+		uint32_t i;
+		struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
+		struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
+		struct msm_cpp_frame_info_t inst_info;
+		for (i = 0; i < MAX_ACTIVE_CPP_INSTANCE; i++) {
+			if (cpp_dev->cpp_subscribe_list[i].vfh == vfh) {
+				inst_info.inst_id = i;
+				break;
+			}
+		}
+		if (copy_to_user(
+				(void __user *)ioctl_ptr->ioctl_ptr, &inst_info,
+				sizeof(struct msm_cpp_frame_info_t))) {
+			return -EINVAL;
+		}
+	}
+	break;
+	default:
+		return v4l2_subdev_call(sd, core, ioctl, cmd, arg);
+	}
+
+	return 0;
+}
+
+static long msm_cpp_subdev_fops_ioctl(struct file *file, unsigned int cmd,
+	unsigned long arg)
+{
+	return video_usercopy(file, cmd, arg, msm_cpp_subdev_do_ioctl);
+}
+
+static int __devinit cpp_probe(struct platform_device *pdev)
+{
+	struct cpp_device *cpp_dev;
+	struct msm_cam_subdev_info sd_info;
+	int rc = 0;
+	CDBG("%s: device id = %d\n", __func__, pdev->id);
+	cpp_dev = kzalloc(sizeof(struct cpp_device), GFP_KERNEL);
+	if (!cpp_dev) {
+		pr_err("%s: no enough memory\n", __func__);
+		return -ENOMEM;
+	}
+	v4l2_subdev_init(&cpp_dev->subdev, &msm_cpp_subdev_ops);
+	cpp_dev->subdev.internal_ops = &msm_cpp_internal_ops;
+	snprintf(cpp_dev->subdev.name, ARRAY_SIZE(cpp_dev->subdev.name),
+		 "cpp");
+	cpp_dev->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	cpp_dev->subdev.flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
+	v4l2_set_subdevdata(&cpp_dev->subdev, cpp_dev);
+	platform_set_drvdata(pdev, &cpp_dev->subdev);
+	mutex_init(&cpp_dev->mutex);
+
+	cpp_dev->pdev = pdev;
+
+	media_entity_init(&cpp_dev->subdev.entity, 0, NULL, 0);
+	cpp_dev->subdev.entity.type = MEDIA_ENT_T_DEVNODE_V4L;
+	cpp_dev->subdev.entity.group_id = CPP_DEV;
+	cpp_dev->subdev.entity.name = pdev->name;
+	sd_info.sdev_type = CPP_DEV;
+	sd_info.sd_index = pdev->id;
+	msm_cam_register_subdev_node(&cpp_dev->subdev, &sd_info);
+	msm_cpp_v4l2_subdev_fops.owner = v4l2_subdev_fops.owner;
+	msm_cpp_v4l2_subdev_fops.open = v4l2_subdev_fops.open;
+	msm_cpp_v4l2_subdev_fops.unlocked_ioctl = msm_cpp_subdev_fops_ioctl;
+	msm_cpp_v4l2_subdev_fops.release = v4l2_subdev_fops.release;
+	msm_cpp_v4l2_subdev_fops.poll = v4l2_subdev_fops.poll;
+
+	cpp_dev->subdev.devnode->fops = &msm_cpp_v4l2_subdev_fops;
+	cpp_dev->subdev.entity.revision = cpp_dev->subdev.devnode->num;
+	msm_cpp_enable_debugfs(cpp_dev);
+	msm_queue_init(&cpp_dev->eventData_q, "eventdata");
+	msm_queue_init(&cpp_dev->offline_q, "frame");
+	msm_queue_init(&cpp_dev->realtime_q, "frame");
+	msm_queue_init(&cpp_dev->processing_q, "frame");
+	cpp_dev->cpp_open_cnt = 0;
+
+	return rc;
+}
+
+static struct platform_driver cpp_driver = {
+	.probe = cpp_probe,
+	.driver = {
+		.name = MSM_CPP_DRV_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init msm_cpp_init_module(void)
+{
+	return platform_driver_register(&cpp_driver);
+}
+
+static void __exit msm_cpp_exit_module(void)
+{
+	platform_driver_unregister(&cpp_driver);
+}
+
+static int msm_cpp_debugfs_stream_s(void *data, u64 val)
+{
+	struct cpp_device *cpp_dev = data;
+	CPP_DBG("CPP processing frame E\n");
+	while (1) {
+		mutex_lock(&cpp_dev->mutex);
+		msm_cpp_notify_frame_done(cpp_dev);
+		msm_cpp_send_frame_to_hardware(cpp_dev);
+		mutex_unlock(&cpp_dev->mutex);
+		msleep(20);
+	}
+	CPP_DBG("CPP processing frame X\n");
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(cpp_debugfs_stream, NULL,
+			msm_cpp_debugfs_stream_s, "%llu\n");
+
+static int msm_cpp_enable_debugfs(struct cpp_device *cpp_dev)
+{
+	struct dentry *debugfs_base;
+	debugfs_base = debugfs_create_dir("msm_camera", NULL);
+	if (!debugfs_base)
+		return -ENOMEM;
+
+	if (!debugfs_create_file("test", S_IRUGO | S_IWUSR, debugfs_base,
+			(void *)cpp_dev, &cpp_debugfs_stream))
+		return -ENOMEM;
+
+	return 0;
+}
+
+module_init(msm_cpp_init_module);
+module_exit(msm_cpp_exit_module);
+MODULE_DESCRIPTION("MSM CPP driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/cpp/msm_cpp.h b/drivers/media/video/msm/cpp/msm_cpp.h
new file mode 100644
index 0000000..8c10cac
--- /dev/null
+++ b/drivers/media/video/msm/cpp/msm_cpp.h
@@ -0,0 +1,65 @@
+/* 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/clk.h>
+#include <linux/io.h>
+#include <linux/list.h>
+#include <media/v4l2-subdev.h>
+
+#define MAX_ACTIVE_CPP_INSTANCE 8
+#define MAX_CPP_PROCESSING_FRAME 2
+#define MAX_CPP_V4l2_EVENTS 30
+
+#define MSM_CPP_MICRO_BASE          0x4000
+#define MSM_CPP_MICRO_HW_VERSION    0x0000
+#define MSM_CPP_MICRO_IRQGEN_STAT   0x0004
+#define MSM_CPP_MICRO_IRQGEN_CLR    0x0008
+#define MSM_CPP_MICRO_IRQGEN_MASK   0x000C
+#define MSM_CPP_MICRO_FIFO_TX_DATA  0x0010
+#define MSM_CPP_MICRO_FIFO_TX_STAT  0x0014
+#define MSM_CPP_MICRO_FIFO_RX_DATA  0x0018
+#define MSM_CPP_MICRO_FIFO_RX_STAT  0x001C
+#define MSM_CPP_MICRO_BOOT_START    0x0020
+#define MSM_CPP_MICRO_BOOT_LDORG    0x0024
+#define MSM_CPP_MICRO_CLKEN_CTL     0x0030
+
+struct cpp_subscribe_info {
+	struct v4l2_fh *vfh;
+	uint32_t active;
+};
+
+struct cpp_device {
+	struct platform_device *pdev;
+	struct v4l2_subdev subdev;
+	struct resource *mem;
+	struct resource *irq;
+	struct resource *io;
+	void __iomem *base;
+	struct clk *cpp_clk[2];
+	struct mutex mutex;
+
+	struct cpp_subscribe_info cpp_subscribe_list[MAX_ACTIVE_CPP_INSTANCE];
+	uint32_t cpp_open_cnt;
+
+	struct msm_device_queue eventData_q; /*V4L2 Event Payload Queue*/
+
+	/*Offline Frame Queue
+	  process when realtime queue is empty*/
+	struct msm_device_queue offline_q;
+	/*Realtime Frame Queue
+	  process with highest priority*/
+	struct msm_device_queue realtime_q;
+	/*Processing Queue
+	  store frame info for frames sent to microcontroller*/
+	struct msm_device_queue processing_q;
+};
+
diff --git a/drivers/media/video/msm/io/msm_camera_i2c.c b/drivers/media/video/msm/io/msm_camera_i2c.c
index cecf9b0..e946569 100644
--- a/drivers/media/video/msm/io/msm_camera_i2c.c
+++ b/drivers/media/video/msm/io/msm_camera_i2c.c
@@ -267,6 +267,35 @@
 	return rc;
 }
 
+int32_t msm_camera_i2c_write_table_w_microdelay(
+	struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_reg_tbl *reg_tbl, uint16_t size,
+	enum msm_camera_i2c_data_type data_type)
+{
+	int i;
+	int32_t rc = -EFAULT;
+
+	if (!client || !reg_tbl)
+		return rc;
+
+	if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
+		&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
+		|| (data_type != MSM_CAMERA_I2C_BYTE_DATA
+		&& data_type != MSM_CAMERA_I2C_WORD_DATA))
+		return rc;
+
+	for (i = 0; i < size; i++) {
+		rc = msm_camera_i2c_write(client, reg_tbl->reg_addr,
+			reg_tbl->reg_data, data_type);
+		if (rc < 0)
+			break;
+		if (reg_tbl->delay)
+			usleep_range(reg_tbl->delay, reg_tbl->delay + 1000);
+		reg_tbl++;
+	}
+	return rc;
+}
+
 int32_t msm_camera_i2c_write_tbl(struct msm_camera_i2c_client *client,
 	struct msm_camera_i2c_reg_conf *reg_conf_tbl, uint16_t size,
 	enum msm_camera_i2c_data_type data_type)
diff --git a/drivers/media/video/msm/io/msm_camera_i2c.h b/drivers/media/video/msm/io/msm_camera_i2c.h
index 01c8259..a0cdd77 100644
--- a/drivers/media/video/msm/io/msm_camera_i2c.h
+++ b/drivers/media/video/msm/io/msm_camera_i2c.h
@@ -58,6 +58,12 @@
 	enum msm_camera_i2c_cmd_type cmd_type;
 };
 
+struct msm_camera_i2c_reg_tbl {
+	uint16_t reg_addr;
+	uint16_t reg_data;
+	uint16_t delay;
+};
+
 struct msm_camera_i2c_conf_array {
 	struct msm_camera_i2c_reg_conf *conf;
 	uint16_t size;
@@ -107,6 +113,11 @@
 	uint16_t addr, uint16_t data,
 	enum msm_camera_i2c_data_type data_type);
 
+int32_t msm_camera_i2c_write_table_w_microdelay(
+	struct msm_camera_i2c_client *client,
+	struct msm_camera_i2c_reg_tbl *reg_tbl, uint16_t size,
+	enum msm_camera_i2c_data_type data_type);
+
 int32_t msm_camera_i2c_write_tbl(struct msm_camera_i2c_client *client,
 	struct msm_camera_i2c_reg_conf *reg_conf_tbl, uint16_t size,
 	enum msm_camera_i2c_data_type data_type);
diff --git a/drivers/media/video/msm/mercury/msm_mercury_platform.c b/drivers/media/video/msm/mercury/msm_mercury_platform.c
index 9366ef3..67ce82d 100644
--- a/drivers/media/video/msm/mercury/msm_mercury_platform.c
+++ b/drivers/media/video/msm/mercury/msm_mercury_platform.c
@@ -11,7 +11,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/pm_qos_params.h>
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/android_pmem.h>
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index d34b8e1..c6fadc0 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -166,17 +166,22 @@
 		struct msm_cam_v4l2_dev_inst, eventHandle);
 	D("%s\n", __func__);
 	WARN_ON(pctx != f->private_data);
+
+	mutex_lock(&pcam_inst->inst_lock);
 	rc = vb2_reqbufs(&pcam_inst->vid_bufq, pb);
 	if (rc < 0) {
 		pr_err("%s reqbufs failed %d ", __func__, rc);
+		mutex_unlock(&pcam_inst->inst_lock);
 		return rc;
 	}
 	if (!pb->count) {
 		/* Deallocation. free buf_offset array */
 		D("%s Inst %p freeing buffer offsets array",
 			__func__, pcam_inst);
-		for (j = 0 ; j < pcam_inst->buf_count ; j++)
+		for (j = 0 ; j < pcam_inst->buf_count ; j++) {
 			kfree(pcam_inst->buf_offset[j]);
+			pcam_inst->buf_offset[j] = NULL;
+		}
 		kfree(pcam_inst->buf_offset);
 		pcam_inst->buf_offset = NULL;
 		/* If the userspace has deallocated all the
@@ -194,6 +199,7 @@
 							GFP_KERNEL);
 		if (!pcam_inst->buf_offset) {
 			pr_err("%s out of memory ", __func__);
+			mutex_unlock(&pcam_inst->inst_lock);
 			return -ENOMEM;
 		}
 		for (i = 0; i < pb->count; i++) {
@@ -202,15 +208,19 @@
 				pcam_inst->plane_info.num_planes, GFP_KERNEL);
 			if (!pcam_inst->buf_offset[i]) {
 				pr_err("%s out of memory ", __func__);
-				for (j = i-1 ; j >= 0; j--)
+				for (j = i-1 ; j >= 0; j--) {
 					kfree(pcam_inst->buf_offset[j]);
+					pcam_inst->buf_offset[j] = NULL;
+				}
 				kfree(pcam_inst->buf_offset);
 				pcam_inst->buf_offset = NULL;
+				mutex_unlock(&pcam_inst->inst_lock);
 				return -ENOMEM;
 			}
 		}
 	}
 	pcam_inst->buf_count = pb->count;
+	mutex_unlock(&pcam_inst->inst_lock);
 	return rc;
 }
 
@@ -218,13 +228,17 @@
 					struct v4l2_buffer *pb)
 {
 	/* get the video device */
+	int rc = 0;
 	struct msm_cam_v4l2_dev_inst *pcam_inst;
 	pcam_inst = container_of(f->private_data,
 		struct msm_cam_v4l2_dev_inst, eventHandle);
 
 	D("%s\n", __func__);
 	WARN_ON(pctx != f->private_data);
-	return vb2_querybuf(&pcam_inst->vid_bufq, pb);
+	mutex_lock(&pcam_inst->inst_lock);
+	rc = vb2_querybuf(&pcam_inst->vid_bufq, pb);
+	mutex_unlock(&pcam_inst->inst_lock);
+	return rc;
 }
 
 static int msm_camera_v4l2_qbuf(struct file *f, void *pctx,
@@ -240,8 +254,10 @@
 		pcam_inst->image_mode, pb->index);
 	WARN_ON(pctx != f->private_data);
 
+	mutex_lock(&pcam_inst->inst_lock);
 	if (!pcam_inst->buf_offset) {
 		pr_err("%s Buffer is already released. Returning.\n", __func__);
+		mutex_unlock(&pcam_inst->inst_lock);
 		return -EINVAL;
 	}
 
@@ -249,6 +265,7 @@
 		/* Reject the buffer if planes array was not allocated */
 		if (pb->m.planes == NULL) {
 			pr_err("%s Planes array is null\n", __func__);
+			mutex_unlock(&pcam_inst->inst_lock);
 			return -EINVAL;
 		}
 		for (i = 0; i < pcam_inst->plane_info.num_planes; i++) {
@@ -269,7 +286,7 @@
 	rc = vb2_qbuf(&pcam_inst->vid_bufq, pb);
 	D("%s, videobuf_qbuf mode %d and idx %d returns %d\n", __func__,
 		pcam_inst->image_mode, pb->index, rc);
-
+	mutex_unlock(&pcam_inst->inst_lock);
 	return rc;
 }
 
@@ -285,6 +302,11 @@
 	D("%s\n", __func__);
 	WARN_ON(pctx != f->private_data);
 
+	mutex_lock(&pcam_inst->inst_lock);
+	if (0 == pcam_inst->streamon) {
+		mutex_unlock(&pcam_inst->inst_lock);
+		return -EACCES;
+	}
 	rc = vb2_dqbuf(&pcam_inst->vid_bufq, pb,  f->f_flags & O_NONBLOCK);
 	D("%s, videobuf_dqbuf returns %d\n", __func__, rc);
 
@@ -292,6 +314,7 @@
 		/* Reject the buffer if planes array was not allocated */
 		if (pb->m.planes == NULL) {
 			pr_err("%s Planes array is null\n", __func__);
+			mutex_unlock(&pcam_inst->inst_lock);
 			return -EINVAL;
 		}
 		for (i = 0; i < pcam_inst->plane_info.num_planes; i++) {
@@ -309,6 +332,7 @@
 		pb->reserved = pcam_inst->buf_offset[pb->index][0].addr_offset;
 	}
 
+	mutex_unlock(&pcam_inst->inst_lock);
 	return rc;
 }
 
@@ -325,9 +349,13 @@
 	D("%s Inst %p\n", __func__, pcam_inst);
 	WARN_ON(pctx != f->private_data);
 
+	mutex_lock(&pcam->vid_lock);
+	mutex_lock(&pcam_inst->inst_lock);
 	if ((buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) &&
 		(buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
 		pr_err("%s Invalid buffer type ", __func__);
+		mutex_unlock(&pcam_inst->inst_lock);
+		mutex_unlock(&pcam->vid_lock);
 		return -EINVAL;
 	}
 
@@ -336,10 +364,10 @@
 	rc = vb2_streamon(&pcam_inst->vid_bufq, buf_type);
 	D("%s, videobuf_streamon returns %d\n", __func__, rc);
 
-	mutex_lock(&pcam->vid_lock);
 	/* turn HW (VFE/sensor) streaming */
 	pcam_inst->streamon = 1;
 	rc = msm_server_streamon(pcam, pcam_inst->my_index);
+	mutex_unlock(&pcam_inst->inst_lock);
 	mutex_unlock(&pcam->vid_lock);
 	D("%s rc = %d\n", __func__, rc);
 	return rc;
@@ -367,16 +395,20 @@
 	/* first turn of HW (VFE/sensor) streaming so that buffers are
 		not in use when we free the buffers */
 	mutex_lock(&pcam->vid_lock);
+	mutex_lock(&pcam_inst->inst_lock);
 	pcam_inst->streamon = 0;
 	if (msm_server_get_usecount() > 0)
 		rc = msm_server_streamoff(pcam, pcam_inst->my_index);
-	mutex_unlock(&pcam->vid_lock);
+
 	if (rc < 0)
 		pr_err("%s: hw failed to stop streaming\n", __func__);
 
 	/* stop buffer streaming */
 	rc = vb2_streamoff(&pcam_inst->vid_bufq, buf_type);
 	D("%s, videobuf_streamoff returns %d\n", __func__, rc);
+
+	mutex_unlock(&pcam_inst->inst_lock);
+	mutex_unlock(&pcam->vid_lock);
 	return rc;
 }
 
@@ -466,11 +498,13 @@
 	D("%s\n", __func__);
 	WARN_ON(pctx != f->private_data);
 
+	mutex_lock(&pcam->vid_lock);
 	rc = msm_server_try_fmt(pcam, pfmt);
 	if (rc)
 		pr_err("Format %x not found, rc = %d\n",
 				pfmt->fmt.pix.pixelformat, rc);
 
+	mutex_unlock(&pcam->vid_lock);
 	return rc;
 }
 
@@ -484,11 +518,13 @@
 	D("%s\n", __func__);
 	WARN_ON(pctx != f->private_data);
 
+	mutex_lock(&pcam->vid_lock);
 	rc = msm_server_try_fmt_mplane(pcam, pfmt);
 	if (rc)
 		pr_err("Format %x not found, rc = %d\n",
 				pfmt->fmt.pix_mp.pixelformat, rc);
 
+	mutex_unlock(&pcam->vid_lock);
 	return rc;
 }
 
@@ -795,6 +831,7 @@
 		mutex_unlock(&pcam->vid_lock);
 		return rc;
 	}
+	mutex_init(&pcam_inst->inst_lock);
 	pcam_inst->sensor_pxlcode = pcam->usr_fmts[0].pxlcode;
 	pcam_inst->my_index = i;
 	pcam_inst->pcam = pcam;
@@ -887,7 +924,9 @@
 		pcam->dev_inst[i] = NULL;
 		pcam->use_count = 0;
 	}
+	pcam->dev_inst[i] = NULL;
 	mutex_unlock(&pcam->vid_lock);
+	mutex_destroy(&pcam_inst->inst_lock);
 	kfree(pcam_inst);
 	pr_err("%s: error end", __func__);
 	return rc;
@@ -986,6 +1025,7 @@
 	}
 
 	mutex_lock(&pcam->vid_lock);
+	mutex_lock(&pcam_inst->inst_lock);
 
 	if (pcam_inst->streamon) {
 		/*something went wrong since instance
@@ -1011,6 +1051,8 @@
 		v4l2_fh_del(&pcam_inst->eventHandle);
 		v4l2_fh_exit(&pcam_inst->eventHandle);
 	}
+	mutex_unlock(&pcam_inst->inst_lock);
+	mutex_destroy(&pcam_inst->inst_lock);
 	kfree(pcam_inst);
 	f->private_data = NULL;
 
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index d0322d1..7d07e7b 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -59,6 +59,7 @@
 #define MSM_MERCURY_DRV_NAME "msm_mercury"
 #define MSM_I2C_MUX_DRV_NAME "msm_cam_i2c_mux"
 #define MSM_IRQ_ROUTER_DRV_NAME "msm_cam_irq_router"
+#define MSM_CPP_DRV_NAME "msm_cpp"
 
 #define MAX_NUM_CSIPHY_DEV 3
 #define MAX_NUM_CSID_DEV 4
@@ -68,6 +69,7 @@
 #define MAX_NUM_AXI_DEV 2
 #define MAX_NUM_VPE_DEV 1
 #define MAX_NUM_JPEG_DEV 3
+#define MAX_NUM_CPP_DEV 1
 
 enum msm_cam_subdev_type {
 	CSIPHY_DEV,
@@ -82,6 +84,7 @@
 	EEPROM_DEV,
 	GESTURE_DEV,
 	IRQ_ROUTER_DEV,
+	CPP_DEV,
 };
 
 /* msm queue management APIs*/
@@ -261,6 +264,7 @@
 	struct v4l2_subdev *vpe_sdev; /* vpe sub device */
 	struct v4l2_subdev *axi_sdev; /* axi sub device */
 	struct v4l2_subdev *eeprom_sdev; /* eeprom sub device */
+	struct v4l2_subdev *cpp_sdev;/*cpp sub device*/
 
 	struct msm_isp_ops *isp_sdev;    /* isp sub device : camif/VFE */
 	struct msm_cam_config_dev *config_device;
@@ -343,6 +347,7 @@
 	int is_mem_map_inst;
 	struct img_plane_info plane_info;
 	int vbqueue_initialized;
+	struct mutex inst_lock;
 };
 
 struct msm_cam_mctl_node {
@@ -540,6 +545,7 @@
 	struct v4l2_subdev *axi_device[MAX_NUM_AXI_DEV];
 	struct v4l2_subdev *vpe_device[MAX_NUM_VPE_DEV];
 	struct v4l2_subdev *gesture_device;
+	struct v4l2_subdev *cpp_device[MAX_NUM_CPP_DEV];
 	struct v4l2_subdev *irqr_device;
 
 	spinlock_t  intr_table_lock;
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index cdfad3b..1359792 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -1123,17 +1123,22 @@
 		struct msm_cam_v4l2_dev_inst, eventHandle);
 	D("%s\n", __func__);
 	WARN_ON(pctx != f->private_data);
+
+	mutex_lock(&pcam_inst->inst_lock);
 	rc = vb2_reqbufs(&pcam_inst->vid_bufq, pb);
 	if (rc < 0) {
 		pr_err("%s reqbufs failed %d ", __func__, rc);
+		mutex_unlock(&pcam_inst->inst_lock);
 		return rc;
 	}
 	if (!pb->count) {
 		/* Deallocation. free buf_offset array */
 		D("%s Inst %p freeing buffer offsets array",
 			__func__, pcam_inst);
-		for (j = 0 ; j < pcam_inst->buf_count ; j++)
+		for (j = 0 ; j < pcam_inst->buf_count ; j++) {
 			kfree(pcam_inst->buf_offset[j]);
+			pcam_inst->buf_offset[j] = NULL;
+		}
 		kfree(pcam_inst->buf_offset);
 		pcam_inst->buf_offset = NULL;
 		/* If the userspace has deallocated all the
@@ -1151,6 +1156,7 @@
 							GFP_KERNEL);
 		if (!pcam_inst->buf_offset) {
 			pr_err("%s out of memory ", __func__);
+			mutex_unlock(&pcam_inst->inst_lock);
 			return -ENOMEM;
 		}
 		for (i = 0; i < pb->count; i++) {
@@ -1159,10 +1165,13 @@
 				pcam_inst->plane_info.num_planes, GFP_KERNEL);
 			if (!pcam_inst->buf_offset[i]) {
 				pr_err("%s out of memory ", __func__);
-				for (j = i-1 ; j >= 0; j--)
+				for (j = i-1 ; j >= 0; j--) {
 					kfree(pcam_inst->buf_offset[j]);
+					pcam_inst->buf_offset[j] = NULL;
+				}
 				kfree(pcam_inst->buf_offset);
 				pcam_inst->buf_offset = NULL;
+				mutex_unlock(&pcam_inst->inst_lock);
 				return -ENOMEM;
 			}
 		}
@@ -1170,6 +1179,7 @@
 	pcam_inst->buf_count = pb->count;
 	D("%s inst %p, buf count %d ", __func__,
 		pcam_inst, pcam_inst->buf_count);
+	mutex_unlock(&pcam_inst->inst_lock);
 	return rc;
 }
 
@@ -1177,13 +1187,17 @@
 					struct v4l2_buffer *pb)
 {
 	/* get the video device */
+	int rc = 0;
 	struct msm_cam_v4l2_dev_inst *pcam_inst;
 	pcam_inst = container_of(f->private_data,
 		struct msm_cam_v4l2_dev_inst, eventHandle);
 
 	D("%s\n", __func__);
 	WARN_ON(pctx != f->private_data);
-	return vb2_querybuf(&pcam_inst->vid_bufq, pb);
+	mutex_lock(&pcam_inst->inst_lock);
+	rc = vb2_querybuf(&pcam_inst->vid_bufq, pb);
+	mutex_unlock(&pcam_inst->inst_lock);
+	return rc;
 }
 
 static int msm_mctl_v4l2_qbuf(struct file *f, void *pctx,
@@ -1198,8 +1212,10 @@
 	D("%s Inst = %p\n", __func__, pcam_inst);
 	WARN_ON(pctx != f->private_data);
 
+	mutex_lock(&pcam_inst->inst_lock);
 	if (!pcam_inst->buf_offset) {
 		pr_err("%s Buffer is already released. Returning. ", __func__);
+		mutex_unlock(&pcam_inst->inst_lock);
 		return -EINVAL;
 	}
 
@@ -1207,6 +1223,7 @@
 		/* Reject the buffer if planes array was not allocated */
 		if (pb->m.planes == NULL) {
 			pr_err("%s Planes array is null ", __func__);
+			mutex_unlock(&pcam_inst->inst_lock);
 			return -EINVAL;
 		}
 		for (i = 0; i < pcam_inst->plane_info.num_planes; i++) {
@@ -1232,6 +1249,7 @@
 	rc = vb2_qbuf(&pcam_inst->vid_bufq, pb);
 	D("%s, videobuf_qbuf returns %d\n", __func__, rc);
 
+	mutex_unlock(&pcam_inst->inst_lock);
 	return rc;
 }
 
@@ -1246,10 +1264,16 @@
 
 	D("%s\n", __func__);
 	WARN_ON(pctx != f->private_data);
+	mutex_lock(&pcam_inst->inst_lock);
+	if (0 == pcam_inst->streamon) {
+		mutex_unlock(&pcam_inst->inst_lock);
+		return -EACCES;
+	}
 
 	rc = vb2_dqbuf(&pcam_inst->vid_bufq, pb,  f->f_flags & O_NONBLOCK);
 	D("%s, videobuf_dqbuf returns %d\n", __func__, rc);
 
+	mutex_unlock(&pcam_inst->inst_lock);
 	return rc;
 }
 
@@ -1266,9 +1290,13 @@
 	D("%s Inst %p\n", __func__, pcam_inst);
 	WARN_ON(pctx != f->private_data);
 
+	mutex_lock(&pcam->mctl_node.dev_lock);
+	mutex_lock(&pcam_inst->inst_lock);
 	if ((buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) &&
 		(buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
 		pr_err("%s Invalid buffer type ", __func__);
+		mutex_unlock(&pcam_inst->inst_lock);
+		mutex_unlock(&pcam->mctl_node.dev_lock);
 		return -EINVAL;
 	}
 
@@ -1277,9 +1305,9 @@
 	rc = vb2_streamon(&pcam_inst->vid_bufq, buf_type);
 	D("%s, videobuf_streamon returns %d\n", __func__, rc);
 
-	mutex_lock(&pcam->mctl_node.dev_lock);
 	/* turn HW (VFE/sensor) streaming */
 	pcam_inst->streamon = 1;
+	mutex_unlock(&pcam_inst->inst_lock);
 	mutex_unlock(&pcam->mctl_node.dev_lock);
 	D("%s rc = %d\n", __func__, rc);
 	return rc;
@@ -1307,14 +1335,16 @@
 	/* first turn of HW (VFE/sensor) streaming so that buffers are
 		not in use when we free the buffers */
 	mutex_lock(&pcam->mctl_node.dev_lock);
+	mutex_lock(&pcam_inst->inst_lock);
 	pcam_inst->streamon = 0;
-	mutex_unlock(&pcam->mctl_node.dev_lock);
 	if (rc < 0)
 		pr_err("%s: hw failed to stop streaming\n", __func__);
 
 	/* stop buffer streaming */
 	rc = vb2_streamoff(&pcam_inst->vid_bufq, buf_type);
 	D("%s, videobuf_streamoff returns %d\n", __func__, rc);
+	mutex_unlock(&pcam_inst->inst_lock);
+	mutex_unlock(&pcam->mctl_node.dev_lock);
 	return rc;
 }
 
diff --git a/drivers/media/video/msm/sensors/imx074_v4l2.c b/drivers/media/video/msm/sensors/imx074_v4l2.c
index 3d23337..ddf0754 100644
--- a/drivers/media/video/msm/sensors/imx074_v4l2.c
+++ b/drivers/media/video/msm/sensors/imx074_v4l2.c
@@ -276,7 +276,7 @@
 	.sensor_config = msm_sensor_config,
 	.sensor_power_up = msm_sensor_power_up,
 	.sensor_power_down = msm_sensor_power_down,
-	.sensor_adjust_frame_lines = msm_sensor_adjust_frame_lines,
+	.sensor_adjust_frame_lines = msm_sensor_adjust_frame_lines1,
 	.sensor_get_csi_params = msm_sensor_get_csi_params,
 };
 
diff --git a/drivers/media/video/msm/sensors/imx091.c b/drivers/media/video/msm/sensors/imx091.c
index 49442e9..7fda037 100644
--- a/drivers/media/video/msm/sensors/imx091.c
+++ b/drivers/media/video/msm/sensors/imx091.c
@@ -303,7 +303,7 @@
 	.sensor_config = msm_sensor_config,
 	.sensor_power_up = msm_sensor_power_up,
 	.sensor_power_down = msm_sensor_power_down,
-	.sensor_adjust_frame_lines = msm_sensor_adjust_frame_lines,
+	.sensor_adjust_frame_lines = msm_sensor_adjust_frame_lines1,
 	.sensor_get_csi_params = msm_sensor_get_csi_params,
 };
 
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index 8ab3963..be1efe0 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -16,7 +16,7 @@
 #include "msm_camera_i2c_mux.h"
 
 /*=============================================================*/
-int32_t msm_sensor_adjust_frame_lines(struct msm_sensor_ctrl_t *s_ctrl,
+int32_t msm_sensor_adjust_frame_lines1(struct msm_sensor_ctrl_t *s_ctrl,
 	uint16_t res)
 {
 	uint16_t cur_line = 0;
@@ -50,6 +50,45 @@
 	return 0;
 }
 
+int32_t msm_sensor_adjust_frame_lines2(struct msm_sensor_ctrl_t *s_ctrl,
+	uint16_t res)
+{
+	uint16_t cur_line = 0;
+	uint16_t exp_fl_lines = 0;
+	uint8_t int_time[3];
+	if (s_ctrl->sensor_exp_gain_info) {
+		if (s_ctrl->prev_gain && s_ctrl->prev_line &&
+			s_ctrl->func_tbl->sensor_write_exp_gain)
+			s_ctrl->func_tbl->sensor_write_exp_gain(
+				s_ctrl,
+				s_ctrl->prev_gain,
+				s_ctrl->prev_line);
+
+		msm_camera_i2c_read_seq(s_ctrl->sensor_i2c_client,
+			s_ctrl->sensor_exp_gain_info->coarse_int_time_addr-1,
+			&int_time[0], 3);
+		cur_line |= int_time[0] << 12;
+		cur_line |= int_time[1] << 4;
+		cur_line |= int_time[2] >> 4;
+		exp_fl_lines = cur_line +
+			s_ctrl->sensor_exp_gain_info->vert_offset;
+		if (exp_fl_lines > s_ctrl->msm_sensor_reg->
+			output_settings[res].frame_length_lines)
+			msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+				s_ctrl->sensor_output_reg_addr->
+				frame_length_lines,
+				exp_fl_lines,
+				MSM_CAMERA_I2C_WORD_DATA);
+		CDBG("%s cur_line %x cur_fl_lines %x, exp_fl_lines %x\n",
+			__func__,
+			cur_line,
+			s_ctrl->msm_sensor_reg->
+			output_settings[res].frame_length_lines,
+			exp_fl_lines);
+	}
+	return 0;
+}
+
 int32_t msm_sensor_write_init_settings(struct msm_sensor_ctrl_t *s_ctrl)
 {
 	int32_t rc;
diff --git a/drivers/media/video/msm/sensors/msm_sensor.h b/drivers/media/video/msm/sensors/msm_sensor.h
index b1e584d..a3ddaa7 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.h
+++ b/drivers/media/video/msm/sensors/msm_sensor.h
@@ -236,7 +236,10 @@
 int32_t msm_sensor_write_output_settings(struct msm_sensor_ctrl_t *s_ctrl,
 	uint16_t res);
 
-int32_t msm_sensor_adjust_frame_lines(struct msm_sensor_ctrl_t *s_ctrl,
+int32_t msm_sensor_adjust_frame_lines1(struct msm_sensor_ctrl_t *s_ctrl,
+	uint16_t res);
+
+int32_t msm_sensor_adjust_frame_lines2(struct msm_sensor_ctrl_t *s_ctrl,
 	uint16_t res);
 
 int32_t msm_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
diff --git a/drivers/media/video/msm/sensors/ov2720.c b/drivers/media/video/msm/sensors/ov2720.c
index 03f1af1..e4c5061 100644
--- a/drivers/media/video/msm/sensors/ov2720.c
+++ b/drivers/media/video/msm/sensors/ov2720.c
@@ -783,7 +783,7 @@
 	.sensor_config = msm_sensor_config,
 	.sensor_power_up = msm_sensor_power_up,
 	.sensor_power_down = msm_sensor_power_down,
-	.sensor_adjust_frame_lines = msm_sensor_adjust_frame_lines,
+	.sensor_adjust_frame_lines = msm_sensor_adjust_frame_lines2,
 	.sensor_get_csi_params = msm_sensor_get_csi_params,
 };
 
diff --git a/drivers/media/video/msm/sensors/s5k3l1yx.c b/drivers/media/video/msm/sensors/s5k3l1yx.c
index d7aeb74..c24da00 100644
--- a/drivers/media/video/msm/sensors/s5k3l1yx.c
+++ b/drivers/media/video/msm/sensors/s5k3l1yx.c
@@ -652,7 +652,7 @@
 	.sensor_config = msm_sensor_config,
 	.sensor_power_up = msm_sensor_power_up,
 	.sensor_power_down = msm_sensor_power_down,
-	.sensor_adjust_frame_lines = msm_sensor_adjust_frame_lines,
+	.sensor_adjust_frame_lines = msm_sensor_adjust_frame_lines1,
 	.sensor_get_csi_params = msm_sensor_get_csi_params,
 };
 
diff --git a/drivers/media/video/msm/server/msm_cam_server.c b/drivers/media/video/msm/server/msm_cam_server.c
index f2bb65f..e21de29 100644
--- a/drivers/media/video/msm/server/msm_cam_server.c
+++ b/drivers/media/video/msm/server/msm_cam_server.c
@@ -637,6 +637,7 @@
 		__func__, tmp_cmd.type, (uint32_t)tmp_cmd.value,
 		tmp_cmd.length, tmp_cmd.status, rc);
 	kfree(ctrl_data);
+	ctrl_data = NULL;
 	return rc;
 }
 
@@ -1894,8 +1895,17 @@
 	case GESTURE_DEV:
 		g_server_dev.gesture_device = sd;
 		break;
+
 	case IRQ_ROUTER_DEV:
 		g_server_dev.irqr_device = sd;
+
+	case CPP_DEV:
+		if (index >= MAX_NUM_CPP_DEV) {
+			pr_err("%s Invalid CPP idx %d", __func__, index);
+			err = -EINVAL;
+			break;
+		}
+		g_server_dev.cpp_device[index] = sd;
 		break;
 	default:
 		break;
@@ -2396,6 +2406,7 @@
 		/* Next, copy the userspace event ctrl structure */
 		if (copy_from_user((void *)&u_isp_event, user_ptr,
 				   sizeof(struct msm_isp_event_ctrl))) {
+			rc = -EFAULT;
 			break;
 		}
 		/* Save the pointer of the user allocated command buffer*/
@@ -2407,6 +2418,7 @@
 			&ev, fp->f_flags & O_NONBLOCK);
 		if (rc < 0) {
 			pr_err("no pending events?");
+			rc = -EFAULT;
 			break;
 		}
 		/* Use k_isp_event to point to the event_ctrl structure
@@ -2436,6 +2448,7 @@
 						break;
 					}
 					kfree(k_msg_value);
+					k_msg_value = NULL;
 				}
 			}
 		}
@@ -2448,6 +2461,7 @@
 			break;
 		}
 		kfree(k_isp_event);
+		k_isp_event = NULL;
 
 		/* Copy the v4l2_event structure back to the user*/
 		if (copy_to_user((void __user *)arg, &ev,
diff --git a/drivers/misc/tsif.c b/drivers/misc/tsif.c
index 2b09d7c..aeda38c 100644
--- a/drivers/misc/tsif.c
+++ b/drivers/misc/tsif.c
@@ -304,7 +304,9 @@
 	for (i = size-1; i >= 0; i--) {
 		int tmp;
 		g = table + i;
-		tmp = gpio_tlmm_config(g->gpio_cfg, GPIO_CFG_DISABLE);
+		tmp = gpio_tlmm_config(GPIO_CFG(GPIO_PIN(g->gpio_cfg),
+			0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+			GPIO_CFG_DISABLE);
 		if (tmp) {
 			pr_err("gpio_tlmm_config(0x%08x, GPIO_CFG_DISABLE)"
 			       " <%s> failed: %d\n",
@@ -681,7 +683,7 @@
 		while (tsif_device->xfer[0].busy ||
 		       tsif_device->xfer[1].busy) {
 			msm_dmov_flush(tsif_device->dma, 1);
-			msleep(10);
+			usleep(10000);
 		}
 	}
 	tsif_device->state = tsif_state_stopped;
@@ -1031,6 +1033,15 @@
 		return rc;
 	}
 	tsif_device->state = tsif_state_running;
+
+	/* make sure the GPIO's are set up */
+	rc = tsif_start_gpios(tsif_device);
+	if (rc) {
+		dev_err(&tsif_device->pdev->dev, "failed to start GPIOs\n");
+		tsif_dma_exit(tsif_device);
+		return rc;
+	}
+
 	/*
 	 * DMA should be scheduled prior to TSIF hardware initialization,
 	 * otherwise "bus error" will be reported by Data Mover
@@ -1046,6 +1057,7 @@
 	rc = tsif_start_hw(tsif_device);
 	if (rc) {
 		dev_err(&tsif_device->pdev->dev, "Unable to start HW\n");
+		tsif_stop_gpios(tsif_device);
 		tsif_dma_exit(tsif_device);
 		tsif_clock(tsif_device, 0);
 		return rc;
@@ -1067,10 +1079,19 @@
 {
 	dev_info(&tsif_device->pdev->dev, "%s, state %d\n", __func__,
 		 (int)tsif_device->state);
-	/*
-	 * DMA should be flushed/stopped prior to TSIF hardware stop,
-	 * otherwise "bus error" will be reported by Data Mover
+
+	/* turn off the GPIO's to prevent new data from entering */
+	tsif_stop_gpios(tsif_device);
+
+	/* we unfortunately must sleep here to give the ADM time to
+	 * complete any outstanding reads after the GPIO's are turned
+	 * off.  There is no indication from the ADM hardware that
+	 * there are any outstanding reads on the bus, and if we
+	 * stop the TSIF too quickly, it can cause a bus error.
 	 */
+	msleep(100);
+
+	/* now we can stop the core */
 	tsif_stop_hw(tsif_device);
 	tsif_dma_exit(tsif_device);
 	tsif_clock(tsif_device, 0);
@@ -1317,9 +1338,6 @@
 	}
 	dev_info(&pdev->dev, "remapped phys 0x%08x => virt %p\n",
 		 tsif_device->memres->start, tsif_device->base);
-	rc = tsif_start_gpios(tsif_device);
-	if (rc)
-		goto err_gpio;
 
 	pm_runtime_set_active(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
@@ -1355,8 +1373,6 @@
 	free_irq(tsif_device->irq, tsif_device);
 err_irq:
 	tsif_debugfs_exit(tsif_device);
-	tsif_stop_gpios(tsif_device);
-err_gpio:
 	iounmap(tsif_device->base);
 err_ioremap:
 err_rgn:
diff --git a/drivers/misc/tspp.c b/drivers/misc/tspp.c
index 81c6b65..4d7553e 100644
--- a/drivers/misc/tspp.c
+++ b/drivers/misc/tspp.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
@@ -1687,7 +1687,7 @@
 
 	/* map clocks */
 	if (data->tsif_pclk) {
-		device->tsif_pclk = clk_get(NULL, data->tsif_pclk);
+		device->tsif_pclk = clk_get(&pdev->dev, data->tsif_pclk);
 		if (IS_ERR(device->tsif_pclk)) {
 			pr_err("tspp: failed to get %s",
 				data->tsif_pclk);
@@ -1697,7 +1697,7 @@
 		}
 	}
 	if (data->tsif_ref_clk) {
-		device->tsif_ref_clk = clk_get(NULL, data->tsif_ref_clk);
+		device->tsif_ref_clk = clk_get(&pdev->dev, data->tsif_ref_clk);
 		if (IS_ERR(device->tsif_ref_clk)) {
 			pr_err("tspp: failed to get %s",
 				data->tsif_ref_clk);
diff --git a/drivers/net/usb/rmnet_usb_ctrl.c b/drivers/net/usb/rmnet_usb_ctrl.c
index a153de1..2972af0 100644
--- a/drivers/net/usb/rmnet_usb_ctrl.c
+++ b/drivers/net/usb/rmnet_usb_ctrl.c
@@ -521,8 +521,6 @@
 	dev->is_opened = 0;
 	mutex_unlock(&dev->dev_lock);
 
-	rmnet_usb_ctrl_stop_rx(dev);
-
 	if (is_dev_connected(dev))
 		usb_kill_anchored_urbs(&dev->tx_submitted);
 
diff --git a/drivers/net/usb/rmnet_usb_data.c b/drivers/net/usb/rmnet_usb_data.c
index 9e1e252..55020a1 100644
--- a/drivers/net/usb/rmnet_usb_data.c
+++ b/drivers/net/usb/rmnet_usb_data.c
@@ -604,6 +604,7 @@
 
 static const struct driver_info rmnet_info_pid9034 = {
 	.description   = "RmNET net device",
+	.flags         = FLAG_SEND_ZLP,
 	.bind          = rmnet_usb_bind,
 	.tx_fixup      = rmnet_usb_tx_fixup,
 	.rx_fixup      = rmnet_usb_rx_fixup,
@@ -613,6 +614,7 @@
 
 static const struct driver_info rmnet_info_pid9048 = {
 	.description   = "RmNET net device",
+	.flags         = FLAG_SEND_ZLP,
 	.bind          = rmnet_usb_bind,
 	.tx_fixup      = rmnet_usb_tx_fixup,
 	.rx_fixup      = rmnet_usb_rx_fixup,
@@ -622,6 +624,7 @@
 
 static const struct driver_info rmnet_info_pid904c = {
 	.description   = "RmNET net device",
+	.flags         = FLAG_SEND_ZLP,
 	.bind          = rmnet_usb_bind,
 	.tx_fixup      = rmnet_usb_tx_fixup,
 	.rx_fixup      = rmnet_usb_rx_fixup,
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c
index be6ba04..e87b4bd 100644
--- a/drivers/power/power_supply_core.c
+++ b/drivers/power/power_supply_core.c
@@ -64,6 +64,24 @@
 EXPORT_SYMBOL_GPL(power_supply_set_online);
 
 /**
+ * power_supply_set_scope - set scope of the power supply
+ * @psy:	the power supply to control
+ * @scope:	value to set the scope property to, should be from
+ *		the SCOPE enum in power_supply.h
+ */
+int power_supply_set_scope(struct power_supply *psy, int scope)
+{
+	const union power_supply_propval ret = {scope, };
+
+	if (psy->set_property)
+		return psy->set_property(psy, POWER_SUPPLY_PROP_SCOPE,
+								&ret);
+
+	return -ENXIO;
+}
+EXPORT_SYMBOL_GPL(power_supply_set_scope);
+
+/**
  * power_supply_set_charge_type - set charge type of the power supply
  * @psy:	the power supply to control
  * @enable:	sets charge type property of power supply
diff --git a/drivers/slimbus/slimbus.c b/drivers/slimbus/slimbus.c
index 24da4d1..36414e0 100644
--- a/drivers/slimbus/slimbus.c
+++ b/drivers/slimbus/slimbus.c
@@ -1979,7 +1979,7 @@
 			}
 		}
 		/* Leave some slots for messaging space */
-		if (opensl1[1] == 0 && opensl1[0] == 0)
+		if (opensl1[1] <= 0 && opensl1[0] <= 0)
 			return -EXFULL;
 		if (opensl1[1] > opensl1[0]) {
 			int temp = opensl1[0];
@@ -2184,7 +2184,7 @@
 			}
 		}
 		/* Leave some slots for messaging space */
-		if (opensl3[1] == 0 && opensl3[0] == 0)
+		if (opensl3[1] <= 0 && opensl3[0] <= 0)
 			return -EXFULL;
 		/* swap 1st and 2nd bucket if 2nd bucket has more open slots */
 		if (opensl3[1] > opensl3[0]) {
diff --git a/drivers/spi/spi_qsd.c b/drivers/spi/spi_qsd.c
index 2c86e83..f2c881d 100644
--- a/drivers/spi/spi_qsd.c
+++ b/drivers/spi/spi_qsd.c
@@ -405,9 +405,17 @@
 			bytes_sent = 0;
 	}
 
-	/* We'll send in chunks of SPI_MAX_LEN if larger */
-	bytes_to_send = dd->tx_bytes_remaining / SPI_MAX_LEN ?
-			  SPI_MAX_LEN : dd->tx_bytes_remaining;
+	/* We'll send in chunks of SPI_MAX_LEN if larger than
+	 * 4K bytes for targets that doesn't support infinite
+	 * mode. Make sure this doesn't happen on targets that
+	 * support infinite mode.
+	 */
+	if (!dd->pdata->infinite_mode)
+		bytes_to_send = dd->tx_bytes_remaining / SPI_MAX_LEN ?
+				SPI_MAX_LEN : dd->tx_bytes_remaining;
+	else
+		bytes_to_send = dd->tx_bytes_remaining;
+
 	num_transfers = DIV_ROUND_UP(bytes_to_send, dd->bytes_per_word);
 	dd->unaligned_len = bytes_to_send % dd->burst_size;
 	num_rows = bytes_to_send / dd->burst_size;
@@ -512,12 +520,11 @@
 		msm_dmov_enqueue_cmd(dd->rx_dma_chan, &dd->rx_hdr);
 }
 
-/* SPI core can send maximum of 4K transfers, because there is HW problem
-   with infinite mode.
-   Therefore, we are sending several chunks of 3K or less (depending on how
-   much is left).
-   Upon completion we send the next chunk, or complete the transfer if
-   everything is finished.
+/* SPI core on targets that does not support infinite mode can send maximum of
+   4K transfers, Therefore, we are sending several chunks of 3K or less
+   (depending on how much is left). Upon completion we send the next chunk,
+   or complete the transfer if everything is finished. On targets that support
+   infinite mode, we send all the bytes in as single chunk.
 */
 static int msm_spi_dm_send_next(struct msm_spi *dd)
 {
@@ -527,8 +534,10 @@
 	if (dd->mode != SPI_DMOV_MODE)
 		return 0;
 
-	/* We need to send more chunks, if we sent max last time */
-	if (dd->tx_bytes_remaining > SPI_MAX_LEN) {
+	/* On targets which does not support infinite mode,
+	   We need to send more chunks, if we sent max last time  */
+	if ((!dd->pdata->infinite_mode) &&
+	    (dd->tx_bytes_remaining > SPI_MAX_LEN)) {
 		dd->tx_bytes_remaining -= SPI_MAX_LEN;
 		if (msm_spi_set_state(dd, SPI_OP_STATE_RESET))
 			return 0;
@@ -1766,6 +1775,8 @@
 
 	of_property_read_u32(node, "spi-max-frequency",
 			&pdata->max_clock_speed);
+	of_property_read_u32(node, "infinite_mode",
+			&pdata->infinite_mode);
 
 	return pdata;
 }
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index 72bc8de..c483bb45 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -73,6 +73,7 @@
 #ifdef CONFIG_SERIAL_MSM_RX_WAKEUP
 	struct msm_wakeup wakeup;
 #endif
+	int			uim;
 };
 
 #define UART_TO_MSM(uart_port)	((struct msm_port *) uart_port)
@@ -500,7 +501,22 @@
 	msm_port->clk_state = MSM_CLK_ON;
 #endif
 
-	if (port->uartclk == 19200000) {
+	if (msm_port->uim) {
+		msm_write(port,
+			UART_SIM_CFG_UIM_TX_MODE |
+			UART_SIM_CFG_UIM_RX_MODE |
+			UART_SIM_CFG_STOP_BIT_LEN_N(1) |
+			UART_SIM_CFG_SIM_CLK_ON |
+			UART_SIM_CFG_SIM_CLK_STOP_HIGH |
+			UART_SIM_CFG_SIM_SEL,
+			UART_SIM_CFG);
+
+		/* (TCXO * 16) / (5 * 372) = TCXO * 16 / 1860 */
+		msm_write(port, 0x08, UART_MREG);
+		msm_write(port, 0x19, UART_NREG);
+		msm_write(port, 0xe8, UART_DREG);
+		msm_write(port, 0x0e, UART_MNDREG);
+	} else if (port->uartclk == 19200000) {
 		/* clock is TCXO (19.2MHz) */
 		msm_write(port, 0x06, UART_MREG);
 		msm_write(port, 0xF1, UART_NREG);
@@ -603,6 +619,11 @@
 {
 	struct msm_port *msm_port = UART_TO_MSM(port);
 
+	if (msm_port->uim)
+		msm_write(port,
+			UART_SIM_CFG_SIM_CLK_STOP_HIGH,
+			UART_SIM_CFG);
+
 	msm_port->imr = 0;
 	msm_write(port, 0, UART_IMR); /* disable interrupts */
 
@@ -1040,6 +1061,39 @@
 	return uart_add_one_port(&msm_uart_driver, port);
 }
 
+static int __init msm_uim_probe(struct platform_device *pdev)
+{
+	struct msm_port *msm_port;
+	struct resource *resource;
+	struct uart_port *port;
+	int irq;
+
+	if (unlikely(pdev->id < 0 || pdev->id >= UART_NR))
+		return -ENXIO;
+
+	pr_info("msm_uim: detected port #%d\n", pdev->id);
+
+	port = get_port_from_line(pdev->id);
+	port->dev = &pdev->dev;
+	msm_port = UART_TO_MSM(port);
+
+	msm_port->uim = true;
+
+	resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (unlikely(!resource))
+		return -ENXIO;
+	port->mapbase = resource->start;
+
+	irq = platform_get_irq(pdev, 0);
+	if (unlikely(irq < 0))
+		return -ENXIO;
+	port->irq = irq;
+
+	platform_set_drvdata(pdev, port);
+
+	return uart_add_one_port(&msm_uart_driver, port);
+}
+
 static int __devexit msm_serial_remove(struct platform_device *pdev)
 {
 	struct msm_port *msm_port = platform_get_drvdata(pdev);
@@ -1125,6 +1179,14 @@
 	},
 };
 
+static struct platform_driver msm_platform_uim_driver = {
+	.remove = msm_serial_remove,
+	.driver = {
+		.name = "msm_uim",
+		.owner = THIS_MODULE,
+	},
+};
+
 static int __init msm_serial_init(void)
 {
 	int ret;
@@ -1137,6 +1199,8 @@
 	if (unlikely(ret))
 		uart_unregister_driver(&msm_uart_driver);
 
+	platform_driver_probe(&msm_platform_uim_driver, msm_uim_probe);
+
 	printk(KERN_INFO "msm_serial: driver initialized\n");
 
 	return ret;
diff --git a/drivers/tty/serial/msm_serial.h b/drivers/tty/serial/msm_serial.h
index 65d0e30..a769825 100644
--- a/drivers/tty/serial/msm_serial.h
+++ b/drivers/tty/serial/msm_serial.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2007 Google, Inc.
  * Author: Robert Love <rlove@google.com>
- * 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
@@ -100,6 +100,16 @@
 #define UART_DREG		0x0030
 #define UART_MNDREG		0x0034
 #define UART_IRDA		0x0038
+
+#define UART_SIM_CFG			0x003c
+#define UART_SIM_CFG_UIM_TX_MODE	(1 << 17)
+#define UART_SIM_CFG_UIM_RX_MODE	(1 << 16)
+#define UART_SIM_CFG_STOP_BIT_LEN_N(n)	((n) << 8)
+#define UART_SIM_CFG_SIM_CLK_ON		(1 << 7)
+#define UART_SIM_CFG_SIM_CLK_TD8_SEL	(1 << 6)
+#define UART_SIM_CFG_SIM_CLK_STOP_HIGH	(1 << 5)
+#define UART_SIM_CFG_SIM_SEL		(1 << 0)
+
 #define UART_MISR_MODE		0x0040
 #define UART_MISR_RESET		0x0044
 #define UART_MISR_EXPORT	0x0048
diff --git a/drivers/tty/serial/msm_serial_hs_lite.c b/drivers/tty/serial/msm_serial_hs_lite.c
index 5735534..ce197be 100644
--- a/drivers/tty/serial/msm_serial_hs_lite.c
+++ b/drivers/tty/serial/msm_serial_hs_lite.c
@@ -122,9 +122,15 @@
 	},
 	{}
 };
+
+#ifdef CONFIG_SERIAL_MSM_HSL_CONSOLE
+static int get_console_state(struct uart_port *port);
+#else
+static inline int get_console_state(struct uart_port *port) { return -ENODEV; };
+#endif
+
 static struct dentry *debug_base;
 static inline void wait_for_xmitr(struct uart_port *port);
-static int get_console_state(struct uart_port *port);
 static inline void msm_hsl_write(struct uart_port *port,
 				 unsigned int val, unsigned int off)
 {
diff --git a/drivers/usb/gadget/u_sdio.c b/drivers/usb/gadget/u_sdio.c
index 8c4b4c7..5e9b0ec 100644
--- a/drivers/usb/gadget/u_sdio.c
+++ b/drivers/usb/gadget/u_sdio.c
@@ -1140,18 +1140,6 @@
 			goto free_sdio_ports;
 		}
 
-#ifdef DEBUG
-		/* REVISIT: create one file per port
-		 * or do not create any file
-		 */
-		if (i == 0) {
-			ret = device_create_file(&g->dev, &dev_attr_input);
-			if (ret)
-				pr_err("%s: unable to create device file\n",
-						__func__);
-		}
-#endif
-
 	}
 
 	gsdio_debugfs_init();
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 3098fbe..fff9465 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -380,6 +380,9 @@
 	ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list);
 	ehci_writel(ehci, (u32) ehci->async->qh_dma, &ehci->regs->async_next);
 
+	/*CMD_RUN will be set after, PORT_RESUME gets cleared*/
+	if (ehci->resume_sof_bug)
+		ehci->command &= ~CMD_RUN;
 	/* restore CMD_RUN, framelist size, and irq threshold */
 	ehci_writel(ehci, ehci->command, &ehci->regs->command);
 	ehci->rh_state = EHCI_RH_RUNNING;
@@ -422,6 +425,17 @@
 		ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
 	}
 
+	if (ehci->resume_sof_bug && resume_needed) {
+		/* root hub has only one port.
+		 * PORT_RESUME gets cleared automatically. */
+		handshake(ehci, &ehci->regs->port_status[0], PORT_RESUME, 0,
+				20000);
+		ehci_writel(ehci, ehci_readl(ehci,
+				&ehci->regs->command) | CMD_RUN,
+				&ehci->regs->command);
+		goto skip_clear_resume;
+	}
+
 	/* msleep for 20ms only if code is trying to resume port */
 	if (resume_needed) {
 		spin_unlock_irq(&ehci->lock);
@@ -438,6 +452,8 @@
 			ehci_vdbg (ehci, "resumed port %d\n", i + 1);
 		}
 	}
+
+skip_clear_resume:
 	(void) ehci_readl(ehci, &ehci->regs->command);
 
 	/* maybe re-activate the schedule(s) */
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index a95198c..874c728 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -730,13 +730,6 @@
 
 skip_phy_resume:
 
-	if (!(readl_relaxed(USB_USBCMD) & CMD_RUN) &&
-			(readl_relaxed(USB_PORTSC) & PORT_SUSPEND)) {
-		writel_relaxed(readl_relaxed(USB_USBCMD) | CMD_RUN ,
-				USB_USBCMD);
-		dbg_log_event(NULL, "Set RS", readl_relaxed(USB_USBCMD));
-	}
-
 	usb_hcd_resume_root_hub(hcd);
 
 	atomic_set(&mehci->in_lpm, 0);
@@ -1246,6 +1239,8 @@
 	mehci->ehci.susp_sof_bug = 1;
 	mehci->ehci.reset_sof_bug = 1;
 
+	mehci->ehci.resume_sof_bug = 1;
+
 	mehci->ehci.max_log2_irq_thresh = 6;
 
 	res = platform_get_resource_byname(pdev,
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 5754170..a0f995c 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -152,6 +152,7 @@
 	unsigned		has_synopsys_hc_bug:1; /* Synopsys HC */
 	unsigned		frame_index_bug:1; /* MosChip (AKA NetMos) */
 	unsigned		susp_sof_bug:1; /*Chip Idea HC*/
+	unsigned		resume_sof_bug:1;/*Chip Idea HC*/
 	unsigned		reset_sof_bug:1; /*Chip Idea HC*/
 
 	/* required for usb32 quirk */
diff --git a/drivers/usb/misc/diag_bridge.c b/drivers/usb/misc/diag_bridge.c
index 8b762a2..6d5544a 100644
--- a/drivers/usb/misc/diag_bridge.c
+++ b/drivers/usb/misc/diag_bridge.c
@@ -255,6 +255,7 @@
 	pipe = usb_sndbulkpipe(dev->udev, dev->out_epAddr);
 	usb_fill_bulk_urb(urb, dev->udev, pipe, data, size,
 				diag_bridge_write_cb, dev);
+	urb->transfer_flags |= URB_ZERO_PACKET;
 	usb_anchor_urb(urb, &dev->submitted);
 	dev->pending_writes++;
 
diff --git a/drivers/usb/misc/mdm_data_bridge.c b/drivers/usb/misc/mdm_data_bridge.c
index db2f40a..1c9de07 100644
--- a/drivers/usb/misc/mdm_data_bridge.c
+++ b/drivers/usb/misc/mdm_data_bridge.c
@@ -497,6 +497,8 @@
 	usb_fill_bulk_urb(txurb, dev->udev, dev->bulk_out,
 			skb->data, skb->len, data_bridge_write_cb, skb);
 
+	txurb->transfer_flags |= URB_ZERO_PACKET;
+
 	if (test_bit(SUSPENDED, &dev->flags)) {
 		usb_anchor_urb(txurb, &dev->delayed);
 		goto free_urb;
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 79bbce4..2bc7f5b 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -51,7 +51,7 @@
 int mdp_rev;
 
 static struct platform_device *mdp_init_pdev;
-static struct regulator *footswitch;
+static struct regulator *footswitch, *hdmi_pll_fs;
 static unsigned int mdp_footswitch_on;
 
 struct completion mdp_ppp_comp;
@@ -2122,10 +2122,16 @@
 	}
 	disable_irq(mdp_irq);
 
+	hdmi_pll_fs = regulator_get(&pdev->dev, "hdmi_pll_fs");
+	if (IS_ERR(hdmi_pll_fs))
+		hdmi_pll_fs = NULL;
+
 	footswitch = regulator_get(&pdev->dev, "vdd");
 	if (IS_ERR(footswitch))
 		footswitch = NULL;
 	else {
+		if (hdmi_pll_fs)
+			regulator_enable(hdmi_pll_fs);
 		regulator_enable(footswitch);
 		mdp_footswitch_on = 1;
 
@@ -2134,6 +2140,8 @@
 			msleep(20);
 			regulator_enable(footswitch);
 		}
+		if (hdmi_pll_fs)
+			regulator_disable(hdmi_pll_fs);
 	}
 
 	mdp_clk = clk_get(&pdev->dev, "core_clk");
@@ -2625,6 +2633,9 @@
 		return;
 	}
 
+	if (hdmi_pll_fs)
+		regulator_enable(hdmi_pll_fs);
+
 	if (on && !mdp_footswitch_on) {
 		pr_debug("Enable MDP FS\n");
 		regulator_enable(footswitch);
@@ -2635,6 +2646,9 @@
 		mdp_footswitch_on = 0;
 	}
 
+	if (hdmi_pll_fs)
+		regulator_disable(hdmi_pll_fs);
+
 	mutex_unlock(&mdp_suspend_mutex);
 }
 
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index 9174bc5..03b22f1 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -520,7 +520,7 @@
 	}
 
 	wait_for_completion_timeout(&dtv_pipe->comp,
-			msecs_to_jiffies(VSYNC_PERIOD*2));
+			msecs_to_jiffies(VSYNC_PERIOD * 3));
 	mdp_disable_irq(MDP_OVERLAY1_TERM);
 
 	if (dtv_pipe->blt_addr)
diff --git a/drivers/video/msm/mdp4_overlay_writeback.c b/drivers/video/msm/mdp4_overlay_writeback.c
index f1a2ada..8dccf78 100644
--- a/drivers/video/msm/mdp4_overlay_writeback.c
+++ b/drivers/video/msm/mdp4_overlay_writeback.c
@@ -21,7 +21,7 @@
 #include <linux/delay.h>
 #include <mach/hardware.h>
 #include <linux/io.h>
-
+#include <mach/iommu_domains.h>
 #include <asm/system.h>
 #include <asm/mach-types.h>
 #include <linux/semaphore.h>
@@ -407,11 +407,10 @@
 			pr_err("%s: out of memory\n", __func__);
 			goto register_alloc_fail;
 		}
-
+		temp->ihdl = NULL;
 		if (data->iova)
 			temp->addr = (void *)(data->iova + data->offset);
-#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-		else {
+		else if (mfd->iclient) {
 			struct ion_handle *srcp_ihdl;
 			ulong len;
 			srcp_ihdl = ion_import_fd(mfd->iclient,
@@ -420,22 +419,30 @@
 				pr_err("%s: ion import fd failed\n", __func__);
 				goto register_ion_fail;
 			}
-			if (ion_phys(mfd->iclient,
-				     srcp_ihdl,
-				     (ulong *)&temp->addr,
-				     (size_t *)&len)) {
-				pr_err("%s: unable to get ion phys\n",
+
+			if (ion_map_iommu(mfd->iclient,
+					  srcp_ihdl,
+					  DISPLAY_DOMAIN,
+					  GEN_POOL,
+					  SZ_4K,
+					  0,
+					  (ulong *)&temp->addr,
+					  (ulong *)&len,
+					  0,
+					  ION_IOMMU_UNMAP_DELAYED)) {
+				ion_free(mfd->iclient, srcp_ihdl);
+				pr_err("%s: unable to get ion mapping addr\n",
 				       __func__);
 				goto register_ion_fail;
 			}
 			temp->addr += data->offset;
+			temp->ihdl = srcp_ihdl;
 		}
-#else
 		else {
 			pr_err("%s: only support ion memory\n", __func__);
 			goto register_ion_fail;
 		}
-#endif
+
 		memcpy(&temp->buf_info, data, sizeof(struct msmfb_data));
 		if (mdp4_overlay_writeback_register_buffer(mfd, temp)) {
 			pr_err("%s: error registering node\n", __func__);
@@ -514,6 +521,15 @@
 		list_del(&node->active_entry);
 		node->state = WITH_CLIENT;
 		memcpy(data, &node->buf_info, sizeof(struct msmfb_data));
+		if (!data->iova)
+			if (mfd->iclient && node->ihdl) {
+				ion_unmap_iommu(mfd->iclient,
+						node->ihdl,
+						DISPLAY_DOMAIN,
+						GEN_POOL);
+				ion_free(mfd->iclient,
+					 node->ihdl);
+			}
 	} else {
 		pr_err("node is NULL. Somebody else dequeued?\n");
 		rc = -ENOBUFS;
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index 41e0c18..46e49da 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -554,10 +554,10 @@
 	}
 	disable_irq(mdss_res->irq);
 
-	mdss_res->fs = regulator_get(NULL, "gdsc_mdss");
+	mdss_res->fs = regulator_get(&pdev->dev, "vdd");
 	if (IS_ERR_OR_NULL(mdss_res->fs)) {
 		mdss_res->fs = NULL;
-		pr_err("unable to get gdsc_mdss regulator\n");
+		pr_err("unable to get gdsc regulator\n");
 		goto error;
 	}
 	regulator_enable(mdss_res->fs);
diff --git a/drivers/video/msm/msm_fb.h b/drivers/video/msm/msm_fb.h
index c9eb7dd..0658365 100644
--- a/drivers/video/msm/msm_fb.h
+++ b/drivers/video/msm/msm_fb.h
@@ -60,6 +60,7 @@
 	struct list_head registered_entry;
 	struct list_head active_entry;
 	void *addr;
+	struct ion_handle *ihdl;
 	struct file *pmem_file;
 	struct msmfb_data buf_info;
 	struct msmfb_img img;
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 6fd5656..d7ebd54 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
@@ -168,6 +168,28 @@
 			} else if (operation == DDL_DPB_OP_MARK_FREE) {
 				dpb_mask->client_mask |= (0x1 << loopc);
 				*found_frame = *in_out_frame;
+				if ((decoder->meta_data_enable_flag) &&
+				    (in_out_frame->vcd_frm.buff_ion_handle)) {
+					struct ddl_context *ddl_context =
+						ddl_get_context();
+					unsigned long *vaddr =
+						(unsigned long *)((u32)
+						in_out_frame->vcd_frm.virtual +
+						decoder->meta_data_offset);
+					DDL_MSG_LOW("%s: Cache clean: vaddr"\
+						" (%p), offset %u, size %u",
+						__func__,
+						in_out_frame->vcd_frm.virtual,
+						decoder->meta_data_offset,
+						decoder->suffix);
+					msm_ion_do_cache_op(
+						ddl_context->video_ion_client,
+						in_out_frame->vcd_frm.\
+						buff_ion_handle,
+						vaddr,
+						(unsigned long)decoder->suffix,
+						ION_IOC_CLEAN_CACHES);
+				}
 			}
 		} else {
 			in_out_frame->vcd_frm.physical = NULL;
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
index 3076aa1..ed8b452 100644
--- a/drivers/video/msm/vidc/common/dec/vdec.c
+++ b/drivers/video/msm/vidc/common/dec/vdec.c
@@ -348,10 +348,15 @@
 				pmem_fd, kernel_vaddr, buffer_index,
 				&buff_handle);
 		if (ion_flag == CACHED && buff_handle) {
+			DBG("%s: Cache invalidate: vaddr (%p), "\
+				"size %u\n", __func__,
+				(void *)kernel_vaddr,
+				vcd_frame_data->alloc_len);
 			msm_ion_do_cache_op(client_ctx->user_ion_client,
 					buff_handle,
 					(unsigned long *) kernel_vaddr,
-					(unsigned long)vcd_frame_data->data_len,
+					(unsigned long)vcd_frame_data->\
+					alloc_len,
 					ION_IOC_INV_CACHES);
 		}
 	}
diff --git a/include/linux/android_pmem.h b/include/linux/android_pmem.h
index ab96379..cfca491 100644
--- a/include/linux/android_pmem.h
+++ b/include/linux/android_pmem.h
@@ -108,26 +108,6 @@
 	PMEM_ALLOCATORTYPE_MAX,
 };
 
-#define PMEM_MEMTYPE_MASK 0x7
-#define PMEM_INVALID_MEMTYPE 0x0
-#define PMEM_MEMTYPE_EBI1 0x1
-#define PMEM_MEMTYPE_SMI  0x2
-#define PMEM_MEMTYPE_RESERVED_INVALID2 0x3
-#define PMEM_MEMTYPE_RESERVED_INVALID3 0x4
-#define PMEM_MEMTYPE_RESERVED_INVALID4 0x5
-#define PMEM_MEMTYPE_RESERVED_INVALID5 0x6
-#define PMEM_MEMTYPE_RESERVED_INVALID6 0x7
-
-#define PMEM_ALIGNMENT_MASK 0x18
-#define PMEM_ALIGNMENT_RESERVED_INVALID1 0x0
-#define PMEM_ALIGNMENT_4K 0x8 /* the default */
-#define PMEM_ALIGNMENT_1M 0x10
-#define PMEM_ALIGNMENT_RESERVED_INVALID2 0x18
-
-/* flags in the following function defined as above. */
-int32_t pmem_kalloc(const size_t size, const uint32_t flags);
-int32_t pmem_kfree(const int32_t physaddr);
-
 /* kernel api names for board specific data structures */
 #define PMEM_KERNEL_EBI1_DATA_NAME "pmem_kernel_ebi1"
 #define PMEM_KERNEL_SMI_DATA_NAME "pmem_kernel_smi"
diff --git a/arch/arm/mach-msm/include/mach/stm.h b/include/linux/coresight-stm.h
similarity index 100%
rename from arch/arm/mach-msm/include/mach/stm.h
rename to include/linux/coresight-stm.h
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
new file mode 100644
index 0000000..f03a493
--- /dev/null
+++ b/include/linux/coresight.h
@@ -0,0 +1,132 @@
+/* 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.
+ */
+
+#ifndef _LINUX_CORESIGHT_H
+#define _LINUX_CORESIGHT_H
+
+#include <linux/device.h>
+
+/* Peripheral id registers (0xFD0-0xFEC) */
+#define CORESIGHT_PERIPHIDR4	(0xFD0)
+#define CORESIGHT_PERIPHIDR5	(0xFD4)
+#define CORESIGHT_PERIPHIDR6	(0xFD8)
+#define CORESIGHT_PERIPHIDR7	(0xFDC)
+#define CORESIGHT_PERIPHIDR0	(0xFE0)
+#define CORESIGHT_PERIPHIDR1	(0xFE4)
+#define CORESIGHT_PERIPHIDR2	(0xFE8)
+#define CORESIGHT_PERIPHIDR3	(0xFEC)
+/* Component id registers (0xFF0-0xFFC) */
+#define CORESIGHT_COMPIDR0	(0xFF0)
+#define CORESIGHT_COMPIDR1	(0xFF4)
+#define CORESIGHT_COMPIDR2	(0xFF8)
+#define CORESIGHT_COMPIDR3	(0xFFC)
+
+/* DBGv7 with baseline CP14 registers implemented */
+#define ARM_DEBUG_ARCH_V7B	(0x3)
+/* DBGv7 with all CP14 registers implemented */
+#define ARM_DEBUG_ARCH_V7	(0x4)
+#define ARM_DEBUG_ARCH_V7_1	(0x5)
+#define ETM_ARCH_V3_3		(0x23)
+#define PFT_ARCH_V1_1		(0x31)
+
+enum coresight_clk_rate {
+	CORESIGHT_CLK_RATE_OFF,
+	CORESIGHT_CLK_RATE_TRACE,
+	CORESIGHT_CLK_RATE_HSTRACE,
+};
+
+enum coresight_dev_type {
+	CORESIGHT_DEV_TYPE_SINK,
+	CORESIGHT_DEV_TYPE_LINK,
+	CORESIGHT_DEV_TYPE_SOURCE,
+	CORESIGHT_DEV_TYPE_MAX,
+};
+
+struct coresight_connection {
+	int child_id;
+	int child_port;
+	struct coresight_device *child_dev;
+	struct list_head link;
+};
+
+struct coresight_device {
+	int id;
+	struct coresight_connection *conns;
+	int nr_conns;
+	const struct coresight_ops *ops;
+	struct device dev;
+	struct mutex mutex;
+	int *refcnt;
+	struct list_head link;
+	struct module *owner;
+	bool enable;
+};
+
+#define to_coresight_device(d) container_of(d, struct coresight_device, dev)
+
+struct coresight_ops {
+	int (*enable)(struct coresight_device *csdev, int port);
+	void (*disable)(struct coresight_device *csdev, int port);
+};
+
+struct coresight_platform_data {
+	int id;
+	const char *name;
+	int nr_ports;
+	int *child_ids;
+	int *child_ports;
+	int nr_children;
+};
+
+struct coresight_desc {
+	enum coresight_dev_type type;
+	const struct coresight_ops *ops;
+	struct coresight_platform_data *pdata;
+	struct device *dev;
+	const struct attribute_group **groups;
+	struct module *owner;
+};
+
+struct qdss_source {
+	struct list_head link;
+	const char *name;
+	uint32_t fport_mask;
+};
+
+struct msm_qdss_platform_data {
+	struct qdss_source *src_table;
+	size_t size;
+	uint8_t afamily;
+};
+
+
+extern struct coresight_device *
+coresight_register(struct coresight_desc *desc);
+extern void coresight_unregister(struct coresight_device *csdev);
+extern int coresight_enable(struct coresight_device *csdev, int port);
+extern void coresight_disable(struct coresight_device *csdev, int port);
+
+#ifdef CONFIG_MSM_QDSS
+extern struct qdss_source *qdss_get(const char *name);
+extern void qdss_put(struct qdss_source *src);
+extern int qdss_enable(struct qdss_source *src);
+extern void qdss_disable(struct qdss_source *src);
+extern void qdss_disable_sink(void);
+#else
+static inline struct qdss_source *qdss_get(const char *name) { return NULL; }
+static inline void qdss_put(struct qdss_source *src) {}
+static inline int qdss_enable(struct qdss_source *src) { return -ENOSYS; }
+static inline void qdss_disable(struct qdss_source *src) {}
+static inline void qdss_disable_sink(void) {}
+#endif
+
+#endif
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 643c80e..32d8ec2 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -216,6 +216,7 @@
 extern int power_supply_set_battery_charged(struct power_supply *psy);
 extern int power_supply_set_current_limit(struct power_supply *psy, int limit);
 extern int power_supply_set_online(struct power_supply *psy, bool enable);
+extern int power_supply_set_scope(struct power_supply *psy, int scope);
 extern int power_supply_set_charge_type(struct power_supply *psy, int type);
 
 #if defined(CONFIG_POWER_SUPPLY) || defined(CONFIG_POWER_SUPPLY_MODULE)
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 3308243..da450fc 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -1659,4 +1659,86 @@
 #define MSM_IRQROUTER_CFG_COMPIRQ \
 	_IOWR('V', BASE_VIDIOC_PRIVATE, void __user *)
 
+#define MAX_NUM_CPP_STRIPS 8
+
+enum msm_cpp_frame_type {
+	MSM_CPP_OFFLINE_FRAME,
+	MSM_CPP_REALTIME_FRAME,
+};
+
+struct msm_cpp_frame_strip_info {
+	int scale_v_en;
+	int scale_h_en;
+
+	int upscale_v_en;
+	int upscale_h_en;
+
+	int src_start_x;
+	int src_end_x;
+	int src_start_y;
+	int src_end_y;
+
+	/* Padding is required for upscaler because it does not
+	 * pad internally like other blocks, also needed for rotation
+	 * rotation expects all the blocks in the stripe to be the same size
+	 * Padding is done such that all the extra padded pixels
+	 * are on the right and bottom
+	*/
+	int pad_bottom;
+	int pad_top;
+	int pad_right;
+	int pad_left;
+
+	int v_init_phase;
+	int h_init_phase;
+	int h_phase_step;
+	int v_phase_step;
+
+	int prescale_crop_width_first_pixel;
+	int prescale_crop_width_last_pixel;
+	int prescale_crop_height_first_line;
+	int prescale_crop_height_last_line;
+
+	int postscale_crop_height_first_line;
+	int postscale_crop_height_last_line;
+	int postscale_crop_width_first_pixel;
+	int postscale_crop_width_last_pixel;
+
+	int dst_start_x;
+	int dst_end_x;
+	int dst_start_y;
+	int dst_end_y;
+
+	int bytes_per_pixel;
+	unsigned int source_address;
+	unsigned int destination_address;
+	unsigned int src_stride;
+	unsigned int dst_stride;
+	int rotate_270;
+	int horizontal_flip;
+	int vertical_flip;
+	int scale_output_width;
+	int scale_output_height;
+};
+
+struct msm_cpp_frame_info_t {
+	int32_t frame_id;
+	uint32_t inst_id;
+	uint32_t client_id;
+	enum msm_cpp_frame_type frame_type;
+	uint32_t num_strips;
+	struct msm_cpp_frame_strip_info *strip_info;
+};
+
+#define VIDIOC_MSM_CPP_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE, struct msm_camera_v4l2_ioctl_t)
+
+#define VIDIOC_MSM_CPP_GET_EVENTPAYLOAD \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct msm_camera_v4l2_ioctl_t)
+
+#define VIDIOC_MSM_CPP_GET_INST_INFO \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 2, struct msm_camera_v4l2_ioctl_t)
+
+#define V4L2_EVENT_CPP_FRAME_DONE  (V4L2_EVENT_PRIVATE_START + 0)
+
 #endif /* __LINUX_MSM_CAMERA_H */
diff --git a/include/sound/apr_audio.h b/include/sound/apr_audio.h
index 431dedf..c770f13 100644
--- a/include/sound/apr_audio.h
+++ b/include/sound/apr_audio.h
@@ -1127,6 +1127,7 @@
 #define AC3_DECODER  0x00010BF6
 #define EAC3_DECODER 0x00010C3C
 #define DTS	0x00010D88
+#define DTS_LBR	0x00010DBB
 #define ATRAC	0x00010D89
 #define MAT	0x00010D8A
 #define G711_ALAW_FS 0x00010BF7
@@ -1145,6 +1146,13 @@
 #define ASM_ENCDEC_IMMDIATE_DECODE 0x00010C14
 #define ASM_ENCDEC_CFG_BLK         0x00010C2C
 
+#define ASM_STREAM_CMD_OPEN_READ_COMPRESSED               0x00010D95
+struct asm_stream_cmd_open_read_compressed {
+	struct apr_hdr hdr;
+	u32            uMode;
+	u32            frame_per_buf;
+} __packed;
+
 #define ASM_STREAM_CMD_OPEN_WRITE                        0x00010BCA
 struct asm_stream_cmd_open_write {
 	struct apr_hdr hdr;
@@ -1185,6 +1193,17 @@
 	u16	afe_port_id;
 } __packed;
 
+#define ADM_CMD_CONNECT_AFE_PORT_V2 0x00010332
+
+struct adm_cmd_connect_afe_port_v2 {
+	struct apr_hdr     hdr;
+	u8	mode; /*mode represent the interface is for RX or TX*/
+	u8	session_id; /*ASM session ID*/
+	u16	afe_port_id;
+	u32	num_channels;
+	u32	sampleing_rate;
+} __packed;
+
 #define ASM_STREAM_CMD_SET_ENCDEC_PARAM                  0x00010C10
 #define ASM_STREAM_CMD_GET_ENCDEC_PARAM                  0x00010C11
 #define ASM_ENCDEC_CFG_BLK_ID				 0x00010C2C
diff --git a/include/sound/compress_offload.h b/include/sound/compress_offload.h
index 9769dea..e59d29c 100644
--- a/include/sound/compress_offload.h
+++ b/include/sound/compress_offload.h
@@ -123,6 +123,16 @@
 };
 
 /**
+ * struct snd_compr_audio_info: compressed input audio information
+ * @frame_size: legth of the encoded frame with valid data
+ * @reserved: reserved for furture use
+ */
+struct snd_compr_audio_info {
+	uint32_t frame_size;
+	uint32_t reserved[15];
+};
+
+/**
  * compress path ioctl definitions
  * SNDRV_COMPRESS_GET_CAPS: Query capability of DSP
  * SNDRV_COMPRESS_GET_CODEC_CAPS: Query capability of a codec
diff --git a/include/sound/compress_params.h b/include/sound/compress_params.h
index 9c7a1ea..75558bf 100644
--- a/include/sound/compress_params.h
+++ b/include/sound/compress_params.h
@@ -70,10 +70,14 @@
 #define SND_AUDIOCODEC_IEC61937              ((__u32) 0x0000000B)
 #define SND_AUDIOCODEC_G723_1                ((__u32) 0x0000000C)
 #define SND_AUDIOCODEC_G729                  ((__u32) 0x0000000D)
-#define SND_AUDIOCODEC_AC3		     ((__u32) 0x0000000E)
-#define SND_AUDIOCODEC_DTS		     ((__u32) 0x0000000F)
-#define SND_AUDIOCODEC_AC3_PASS_THROUGH		((__u32) 0x00000010)
-#define SND_AUDIOCODEC_WMA_PRO		     ((__u32) 0x00000011)
+#define SND_AUDIOCODEC_AC3                   ((__u32) 0x0000000E)
+#define SND_AUDIOCODEC_DTS                   ((__u32) 0x0000000F)
+#define SND_AUDIOCODEC_AC3_PASS_THROUGH      ((__u32) 0x00000010)
+#define SND_AUDIOCODEC_WMA_PRO               ((__u32) 0x00000011)
+#define SND_AUDIOCODEC_DTS_PASS_THROUGH      ((__u32) 0x00000012)
+#define SND_AUDIOCODEC_DTS_LBR               ((__u32) 0x00000013)
+#define SND_AUDIOCODEC_DTS_TRANSCODE_LOOPBACK ((__u32) 0x00000014)
+
 /*
  * Profile and modes are listed with bit masks. This allows for a
  * more compact representation of fields that will not evolve
diff --git a/include/sound/q6asm.h b/include/sound/q6asm.h
index 1e647a2..84e3150 100644
--- a/include/sound/q6asm.h
+++ b/include/sound/q6asm.h
@@ -48,6 +48,7 @@
 #define FORMAT_ATRAC	0x0016
 #define FORMAT_MAT	0x0017
 #define FORMAT_AAC	0x0018
+#define FORMAT_DTS_LBR 0x0019
 
 #define ENCDEC_SBCBITRATE   0x0001
 #define ENCDEC_IMMEDIATE_DECODE 0x0002
@@ -180,6 +181,8 @@
 
 int q6asm_open_read(struct audio_client *ac, uint32_t format);
 
+int q6asm_open_read_compressed(struct audio_client *ac, uint32_t format);
+
 int q6asm_open_write(struct audio_client *ac, uint32_t format);
 
 int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format);
diff --git a/kernel/panic.c b/kernel/panic.c
index b47ca87..8c6babc 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -81,6 +81,14 @@
 	int state = 0;
 
 	/*
+	 * Disable local interrupts. This will prevent panic_smp_self_stop
+	 * from deadlocking the first cpu that invokes the panic, since
+	 * there is nothing to prevent an interrupt handler (that runs
+	 * after the panic_lock is acquired) from invoking panic again.
+	 */
+	local_irq_disable();
+
+	/*
 	 * It's possible to come here directly from a panic-assertion and
 	 * not have preempt disabled. Some functions called from here want
 	 * preempt to be disabled. No point enabling it later though...
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index e85e9f5..a34b294 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -114,6 +114,11 @@
 static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
 static struct snd_soc_dai_driver tabla_dai[];
 static const DECLARE_TLV_DB_SCALE(aux_pga_gain, 0, 2, 0);
+static int tabla_codec_enable_slimrx(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event);
+static int tabla_codec_enable_slimtx(struct snd_soc_dapm_widget *w,
+	struct snd_kcontrol *kcontrol, int event);
+
 
 enum tabla_bandgap_type {
 	TABLA_BANDGAP_OFF = 0,
@@ -3931,50 +3936,277 @@
 	return 0;
 }
 
+
+static struct snd_soc_dapm_widget tabla_dapm_aif_in_widgets[] = {
+
+	SND_SOC_DAPM_AIF_IN_E("SLIM RX1", "AIF1 Playback", 0, SND_SOC_NOPM, 1,
+				0, tabla_codec_enable_slimrx,
+				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_AIF_IN_E("SLIM RX2", "AIF1 Playback", 0, SND_SOC_NOPM, 2,
+				0, tabla_codec_enable_slimrx,
+				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_AIF_IN_E("SLIM RX3", "AIF1 Playback", 0, SND_SOC_NOPM, 3,
+				0, tabla_codec_enable_slimrx,
+				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_AIF_IN_E("SLIM RX4", "AIF3 Playback", 0, SND_SOC_NOPM, 4,
+				0, tabla_codec_enable_slimrx,
+				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_AIF_IN_E("SLIM RX5", "AIF3 Playback", 0, SND_SOC_NOPM, 5,
+				0, tabla_codec_enable_slimrx,
+				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_AIF_IN_E("SLIM RX6", "AIF2 Playback", 0, SND_SOC_NOPM, 6,
+				0, tabla_codec_enable_slimrx,
+				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_AIF_IN_E("SLIM RX7", "AIF2 Playback", 0, SND_SOC_NOPM, 7,
+				0, tabla_codec_enable_slimrx,
+				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+};
+
+static struct snd_soc_dapm_widget tabla_dapm_aif_out_widgets[] = {
+
+	SND_SOC_DAPM_AIF_OUT_E("SLIM TX1", "AIF2 Capture", 0, SND_SOC_NOPM, 1,
+				0, tabla_codec_enable_slimtx,
+				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_AIF_OUT_E("SLIM TX2", "AIF2 Capture", 0, SND_SOC_NOPM, 2,
+				0, tabla_codec_enable_slimtx,
+				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_AIF_OUT_E("SLIM TX3", "AIF3 Capture", 0, SND_SOC_NOPM, 3,
+				0, tabla_codec_enable_slimtx,
+				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_AIF_OUT_E("SLIM TX4", "AIF2 Capture", 0, SND_SOC_NOPM, 4,
+				0, tabla_codec_enable_slimtx,
+				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_AIF_OUT_E("SLIM TX5", "AIF3 Capture", 0, SND_SOC_NOPM, 5,
+				0, tabla_codec_enable_slimtx,
+				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_AIF_OUT_E("SLIM TX6", "AIF2 Capture", 0, SND_SOC_NOPM, 6,
+				0, tabla_codec_enable_slimtx,
+				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_AIF_OUT_E("SLIM TX7", "AIF1 Capture", 0, SND_SOC_NOPM, 7,
+				0, tabla_codec_enable_slimtx,
+				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_AIF_OUT_E("SLIM TX8", "AIF1 Capture", 0, SND_SOC_NOPM, 8,
+				0, tabla_codec_enable_slimtx,
+				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_AIF_OUT_E("SLIM TX9", "AIF1 Capture", 0, SND_SOC_NOPM, 9,
+				0, tabla_codec_enable_slimtx,
+				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_AIF_OUT_E("SLIM TX10", "AIF1 Capture", 0, SND_SOC_NOPM, 10,
+				0, tabla_codec_enable_slimtx,
+				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+};
+
+static int tabla_set_interpolator_rate(struct snd_soc_dai *dai,
+	u8 rx_fs_rate_reg_val, u32 compander_fs, u32 sample_rate)
+{
+	u32 i, j;
+	u8 rx_mix1_inp;
+	u16 rx_mix_1_reg_1, rx_mix_1_reg_2;
+	u16 rx_fs_reg;
+	u8 rx_mix_1_reg_1_val, rx_mix_1_reg_2_val;
+	struct snd_soc_codec *codec = dai->codec;
+	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
+	struct snd_soc_dapm_widget *w = tabla_dapm_aif_in_widgets;
+
+	for (i = 0; i < ARRAY_SIZE(tabla_dapm_aif_in_widgets); i++) {
+
+		if (strncmp(dai->driver->playback.stream_name, w[i].sname, 13))
+			continue;
+
+		rx_mix1_inp = w[i].shift + 4;
+
+		if ((rx_mix1_inp < 0x5) || (rx_mix1_inp > 0xB)) {
+
+			pr_err("%s: Invalid SLIM RX%u port.  widget = %s\n",
+				__func__,  rx_mix1_inp  - 4 , w[i].name);
+			return -EINVAL;
+		}
+
+		rx_mix_1_reg_1 = TABLA_A_CDC_CONN_RX1_B1_CTL;
+
+		for (j = 0; j < NUM_INTERPOLATORS; j++) {
+
+			rx_mix_1_reg_2 = rx_mix_1_reg_1 + 1;
+
+			rx_mix_1_reg_1_val = snd_soc_read(codec,
+					rx_mix_1_reg_1);
+			rx_mix_1_reg_2_val = snd_soc_read(codec,
+					rx_mix_1_reg_2);
+
+			if (((rx_mix_1_reg_1_val & 0x0F) == rx_mix1_inp) ||
+			   (((rx_mix_1_reg_1_val >> 4) & 0x0F) == rx_mix1_inp)
+			   || ((rx_mix_1_reg_2_val & 0x0F) == rx_mix1_inp)) {
+
+				rx_fs_reg = TABLA_A_CDC_RX1_B5_CTL + 8 * j;
+
+				pr_debug("%s: %s connected to RX%u\n", __func__,
+					w[i].name, j + 1);
+
+				pr_debug("%s: set RX%u sample rate to %u\n",
+					__func__, j + 1, sample_rate);
+
+				snd_soc_update_bits(codec, rx_fs_reg,
+						0xE0, rx_fs_rate_reg_val);
+
+				if (comp_rx_path[j] < COMPANDER_MAX)
+					tabla->comp_fs[comp_rx_path[j]]
+					= compander_fs;
+			}
+			if (j <= 2)
+				rx_mix_1_reg_1 += 3;
+			else
+				rx_mix_1_reg_1 += 2;
+		}
+	}
+	return 0;
+}
+
+static int tabla_set_decimator_rate(struct snd_soc_dai *dai,
+	u8 tx_fs_rate_reg_val, u32 sample_rate)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	struct snd_soc_dapm_widget *w = tabla_dapm_aif_out_widgets;
+
+	u32 i, tx_port;
+	u16 tx_port_reg, tx_fs_reg;
+	u8 tx_port_reg_val;
+	s8 decimator;
+
+	for (i = 0; i < ARRAY_SIZE(tabla_dapm_aif_out_widgets); i++) {
+
+		if (strncmp(dai->driver->capture.stream_name, w[i].sname, 12))
+			continue;
+
+		tx_port = w[i].shift;
+
+		if ((tx_port < 1) || (tx_port > NUM_DECIMATORS)) {
+			pr_err("%s: Invalid SLIM TX%u port.  widget = %s\n",
+				__func__, tx_port, w[i].name);
+			return -EINVAL;
+		}
+
+		tx_port_reg = TABLA_A_CDC_CONN_TX_SB_B1_CTL + (tx_port - 1);
+		tx_port_reg_val =  snd_soc_read(codec, tx_port_reg);
+
+		decimator = 0;
+
+		if ((tx_port >= 1) && (tx_port <= 6)) {
+
+			tx_port_reg_val =  tx_port_reg_val & 0x0F;
+			if (tx_port_reg_val == 0x8)
+				decimator = tx_port;
+
+		} else if ((tx_port >= 7) && (tx_port <= NUM_DECIMATORS)) {
+
+			tx_port_reg_val =  tx_port_reg_val & 0x1F;
+
+			if ((tx_port_reg_val >= 0x8) &&
+			    (tx_port_reg_val <= 0x11)) {
+
+				decimator = (tx_port_reg_val - 0x8) + 1;
+			}
+		}
+
+		if (decimator) { /* SLIM_TX port has a DEC as input */
+
+			tx_fs_reg = TABLA_A_CDC_TX1_CLK_FS_CTL +
+				8 * (decimator - 1);
+
+			pr_debug("%s: set DEC%u (-> SLIM_TX%u) rate to %u\n",
+				__func__, decimator, tx_port, sample_rate);
+
+			snd_soc_update_bits(codec, tx_fs_reg, 0x07,
+					tx_fs_rate_reg_val);
+
+		} else {
+			if ((tx_port_reg_val >= 0x1) &&
+					(tx_port_reg_val <= 0x7)) {
+
+				pr_debug("%s: RMIX%u going to SLIM TX%u\n",
+					__func__, tx_port_reg_val, tx_port);
+
+			} else if  ((tx_port_reg_val >= 0x8) &&
+					(tx_port_reg_val <= 0x11)) {
+
+				pr_err("%s: ERROR: Should not be here\n",
+						__func__);
+				pr_err("%s: ERROR: DEC connected to SLIM TX%u\n"
+						, __func__, tx_port);
+				return -EINVAL;
+
+			} else if (tx_port_reg_val == 0) {
+				pr_debug("%s: no signal to SLIM TX%u\n",
+						__func__, tx_port);
+			} else {
+				pr_err("%s: ERROR: wrong signal to SLIM TX%u\n"
+						, __func__, tx_port);
+				pr_err("%s: ERROR: wrong signal = %u\n"
+						, __func__, tx_port_reg_val);
+				return -EINVAL;
+			}
+		}
+	}
+	return 0;
+}
+
 static int tabla_hw_params(struct snd_pcm_substream *substream,
-			    struct snd_pcm_hw_params *params,
-			    struct snd_soc_dai *dai)
+		struct snd_pcm_hw_params *params,
+		struct snd_soc_dai *dai)
 {
 	struct snd_soc_codec *codec = dai->codec;
 	struct tabla_priv *tabla = snd_soc_codec_get_drvdata(dai->codec);
-	u8 path, shift;
-	u16 tx_fs_reg, rx_fs_reg;
-	u8 tx_fs_rate, rx_fs_rate, rx_state, tx_state;
+	u8 tx_fs_rate_reg_val, rx_fs_rate_reg_val;
 	u32 compander_fs;
+	int ret;
 
 	pr_debug("%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n", __func__,
-		 dai->name, dai->id, params_rate(params),
-		 params_channels(params));
+			dai->name, dai->id, params_rate(params),
+			params_channels(params));
 
 	switch (params_rate(params)) {
 	case 8000:
-		tx_fs_rate = 0x00;
-		rx_fs_rate = 0x00;
+		tx_fs_rate_reg_val = 0x00;
+		rx_fs_rate_reg_val = 0x00;
 		compander_fs = COMPANDER_FS_8KHZ;
 		break;
 	case 16000:
-		tx_fs_rate = 0x01;
-		rx_fs_rate = 0x20;
+		tx_fs_rate_reg_val = 0x01;
+		rx_fs_rate_reg_val = 0x20;
 		compander_fs = COMPANDER_FS_16KHZ;
 		break;
 	case 32000:
-		tx_fs_rate = 0x02;
-		rx_fs_rate = 0x40;
+		tx_fs_rate_reg_val = 0x02;
+		rx_fs_rate_reg_val = 0x40;
 		compander_fs = COMPANDER_FS_32KHZ;
 		break;
 	case 48000:
-		tx_fs_rate = 0x03;
-		rx_fs_rate = 0x60;
+		tx_fs_rate_reg_val = 0x03;
+		rx_fs_rate_reg_val = 0x60;
 		compander_fs = COMPANDER_FS_48KHZ;
 		break;
 	case 96000:
-		tx_fs_rate = 0x04;
-		rx_fs_rate = 0x80;
+		tx_fs_rate_reg_val = 0x04;
+		rx_fs_rate_reg_val = 0x80;
 		compander_fs = COMPANDER_FS_96KHZ;
 		break;
 	case 192000:
-		tx_fs_rate = 0x05;
-		rx_fs_rate = 0xA0;
+		tx_fs_rate_reg_val = 0x05;
+		rx_fs_rate_reg_val = 0xA0;
 		compander_fs = COMPANDER_FS_192KHZ;
 		break;
 	default:
@@ -3983,105 +4215,76 @@
 		return -EINVAL;
 	}
 
+	switch (substream->stream) {
+	case SNDRV_PCM_STREAM_CAPTURE:
 
-	/**
-	 * If current dai is a tx dai, set sample rate to
-	 * all the txfe paths that are currently not active
-	 */
-	if ((dai->id == AIF1_CAP) || (dai->id == AIF2_CAP) ||
-	    (dai->id == AIF3_CAP)) {
-
-		tx_state = snd_soc_read(codec,
-				TABLA_A_CDC_CLK_TX_CLK_EN_B1_CTL);
-
-		for (path = 1, shift = 0;
-				path <= NUM_DECIMATORS; path++, shift++) {
-
-			if (path == BITS_PER_REG + 1) {
-				shift = 0;
-				tx_state = snd_soc_read(codec,
-					TABLA_A_CDC_CLK_TX_CLK_EN_B2_CTL);
-			}
-
-			if (!(tx_state & (1 << shift))) {
-				tx_fs_reg = TABLA_A_CDC_TX1_CLK_FS_CTL
-						+ (BITS_PER_REG*(path-1));
-				snd_soc_update_bits(codec, tx_fs_reg,
-							0x07, tx_fs_rate);
-			}
+		ret = tabla_set_decimator_rate(dai, tx_fs_rate_reg_val,
+				params_rate(params));
+		if (ret < 0) {
+			pr_err("%s: set decimator rate failed %d\n", __func__,
+					ret);
+			return ret;
 		}
+
 		if (tabla->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
 			switch (params_format(params)) {
 			case SNDRV_PCM_FORMAT_S16_LE:
 				snd_soc_update_bits(codec,
-					TABLA_A_CDC_CLK_TX_I2S_CTL,
-					0x20, 0x20);
+					TABLA_A_CDC_CLK_TX_I2S_CTL, 0x20, 0x20);
 				break;
 			case SNDRV_PCM_FORMAT_S32_LE:
 				snd_soc_update_bits(codec,
-					TABLA_A_CDC_CLK_TX_I2S_CTL,
-					0x20, 0x00);
+					TABLA_A_CDC_CLK_TX_I2S_CTL, 0x20, 0x00);
 				break;
 			default:
-				pr_err("invalid format\n");
-				break;
+				pr_err("%s: invalid TX format %u\n", __func__,
+						params_format(params));
+				return -EINVAL;
 			}
 			snd_soc_update_bits(codec, TABLA_A_CDC_CLK_TX_I2S_CTL,
-						0x07, tx_fs_rate);
+					0x07, tx_fs_rate_reg_val);
 		} else {
 			tabla->dai[dai->id - 1].rate   = params_rate(params);
 		}
-	}
-	/**
-	 * TODO: Need to handle case where same RX chain takes 2 or more inputs
-	 * with varying sample rates
-	 */
+		break;
 
-	/**
-	 * If current dai is a rx dai, set sample rate to
-	 * all the rx paths that are currently not active
-	 */
-	if (dai->id == AIF1_PB || dai->id == AIF2_PB || dai->id == AIF3_PB) {
+	case SNDRV_PCM_STREAM_PLAYBACK:
 
-		rx_state = snd_soc_read(codec,
-			TABLA_A_CDC_CLK_RX_B1_CTL);
-
-		for (path = 1, shift = 0;
-				path <= NUM_INTERPOLATORS; path++, shift++) {
-
-			if (!(rx_state & (1 << shift))) {
-				rx_fs_reg = TABLA_A_CDC_RX1_B5_CTL
-						+ (BITS_PER_REG*(path-1));
-				snd_soc_update_bits(codec, rx_fs_reg,
-						0xE0, rx_fs_rate);
-				if (comp_rx_path[shift] < COMPANDER_MAX)
-					tabla->comp_fs[comp_rx_path[shift]]
-					= compander_fs;
-			}
+		ret = tabla_set_interpolator_rate(dai, rx_fs_rate_reg_val,
+				compander_fs, params_rate(params));
+		if (ret < 0) {
+			pr_err("%s: set decimator rate failed %d\n", __func__,
+					ret);
+			return ret;
 		}
+
 		if (tabla->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
 			switch (params_format(params)) {
 			case SNDRV_PCM_FORMAT_S16_LE:
 				snd_soc_update_bits(codec,
-					TABLA_A_CDC_CLK_RX_I2S_CTL,
-					0x20, 0x20);
+					TABLA_A_CDC_CLK_RX_I2S_CTL, 0x20, 0x20);
 				break;
 			case SNDRV_PCM_FORMAT_S32_LE:
 				snd_soc_update_bits(codec,
-					TABLA_A_CDC_CLK_RX_I2S_CTL,
-					0x20, 0x00);
+					TABLA_A_CDC_CLK_RX_I2S_CTL, 0x20, 0x00);
 				break;
 			default:
-				pr_err("invalid format\n");
-				break;
+				pr_err("%s: invalid RX format %u\n", __func__,
+						params_format(params));
+				return -EINVAL;
 			}
 			snd_soc_update_bits(codec, TABLA_A_CDC_CLK_RX_I2S_CTL,
-						0x03, (rx_fs_rate >> 0x05));
+					0x03, (rx_fs_rate_reg_val >> 0x05));
 		} else {
 			tabla->dai[dai->id - 1].rate   = params_rate(params);
 		}
-	}
+		break;
 
+	default:
+		pr_err("%s: Invalid stream type %d\n", __func__,
+				substream->stream);
+		return -EINVAL;
+	}
 	return 0;
 }
 
@@ -4350,30 +4553,6 @@
 	SND_SOC_DAPM_MIXER("DAC1", TABLA_A_RX_EAR_EN, 6, 0, dac1_switch,
 		ARRAY_SIZE(dac1_switch)),
 
-	SND_SOC_DAPM_AIF_IN_E("SLIM RX1", "AIF1 Playback", 0, SND_SOC_NOPM, 0,
-				0, tabla_codec_enable_slimrx,
-				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_AIF_IN_E("SLIM RX2", "AIF1 Playback", 0, SND_SOC_NOPM, 0,
-				0, tabla_codec_enable_slimrx,
-				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_AIF_IN_E("SLIM RX3", "AIF1 Playback", 0, SND_SOC_NOPM, 0,
-				0, tabla_codec_enable_slimrx,
-				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
-	SND_SOC_DAPM_AIF_IN_E("SLIM RX4", "AIF3 Playback", 0, SND_SOC_NOPM, 0,
-				0, tabla_codec_enable_slimrx,
-				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_AIF_IN_E("SLIM RX5", "AIF3 Playback", 0, SND_SOC_NOPM, 0,
-				0, tabla_codec_enable_slimrx,
-				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
-	SND_SOC_DAPM_AIF_IN_E("SLIM RX6", "AIF2 Playback", 0, SND_SOC_NOPM, 0,
-				0, tabla_codec_enable_slimrx,
-				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-	SND_SOC_DAPM_AIF_IN_E("SLIM RX7", "AIF2 Playback", 0, SND_SOC_NOPM, 0,
-				0, tabla_codec_enable_slimrx,
-				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
 	/* Headphone */
 	SND_SOC_DAPM_OUTPUT("HEADPHONE"),
 	SND_SOC_DAPM_PGA_E("HPHL", TABLA_A_RX_HPH_CNP_EN, 5, 0, NULL, 0,
@@ -4654,54 +4833,15 @@
 		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
 
 	SND_SOC_DAPM_MUX("SLIM TX1 MUX", SND_SOC_NOPM, 0, 0, &sb_tx1_mux),
-	SND_SOC_DAPM_AIF_OUT_E("SLIM TX1", "AIF2 Capture", 0, SND_SOC_NOPM, 0,
-				0, tabla_codec_enable_slimtx,
-				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
 	SND_SOC_DAPM_MUX("SLIM TX2 MUX", SND_SOC_NOPM, 0, 0, &sb_tx2_mux),
-	SND_SOC_DAPM_AIF_OUT_E("SLIM TX2", "AIF2 Capture", 0, SND_SOC_NOPM, 0,
-				0, tabla_codec_enable_slimtx,
-				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
 	SND_SOC_DAPM_MUX("SLIM TX3 MUX", SND_SOC_NOPM, 0, 0, &sb_tx3_mux),
-	SND_SOC_DAPM_AIF_OUT_E("SLIM TX3", "AIF3 Capture", 0, SND_SOC_NOPM, 0,
-				0, tabla_codec_enable_slimtx,
-				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
 	SND_SOC_DAPM_MUX("SLIM TX4 MUX", SND_SOC_NOPM, 0, 0, &sb_tx4_mux),
-	SND_SOC_DAPM_AIF_OUT_E("SLIM TX4", "AIF2 Capture", 0, SND_SOC_NOPM, 0,
-				0, tabla_codec_enable_slimtx,
-				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
 	SND_SOC_DAPM_MUX("SLIM TX5 MUX", SND_SOC_NOPM, 0, 0, &sb_tx5_mux),
-	SND_SOC_DAPM_AIF_OUT_E("SLIM TX5", "AIF3 Capture", 0, SND_SOC_NOPM, 0,
-				0, tabla_codec_enable_slimtx,
-				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
 	SND_SOC_DAPM_MUX("SLIM TX6 MUX", SND_SOC_NOPM, 0, 0, &sb_tx6_mux),
-	SND_SOC_DAPM_AIF_OUT_E("SLIM TX6", "AIF2 Capture", 0, SND_SOC_NOPM, 0,
-				0, tabla_codec_enable_slimtx,
-				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
 	SND_SOC_DAPM_MUX("SLIM TX7 MUX", SND_SOC_NOPM, 0, 0, &sb_tx7_mux),
-	SND_SOC_DAPM_AIF_OUT_E("SLIM TX7", "AIF1 Capture", 0, SND_SOC_NOPM, 0,
-				0, tabla_codec_enable_slimtx,
-				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
 	SND_SOC_DAPM_MUX("SLIM TX8 MUX", SND_SOC_NOPM, 0, 0, &sb_tx8_mux),
-	SND_SOC_DAPM_AIF_OUT_E("SLIM TX8", "AIF1 Capture", 0, SND_SOC_NOPM, 0,
-				0, tabla_codec_enable_slimtx,
-				SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
 	SND_SOC_DAPM_MUX("SLIM TX9 MUX", SND_SOC_NOPM, 0, 0, &sb_tx9_mux),
-	SND_SOC_DAPM_AIF_OUT_E("SLIM TX9", "AIF1 Capture", NULL, SND_SOC_NOPM,
-			0, 0, tabla_codec_enable_slimtx,
-			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
 	SND_SOC_DAPM_MUX("SLIM TX10 MUX", SND_SOC_NOPM, 0, 0, &sb_tx10_mux),
-	SND_SOC_DAPM_AIF_OUT_E("SLIM TX10", "AIF1 Capture", NULL, SND_SOC_NOPM,
-			0, 0, tabla_codec_enable_slimtx,
-			SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
 
 	/* Digital Mic Inputs */
 	SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 0, 0,
@@ -7560,6 +7700,13 @@
 
 //	snd_soc_dapm_new_controls(dapm, tabla_dapm_widgets,
 //				  ARRAY_SIZE(tabla_dapm_widgets));
+
+	snd_soc_dapm_new_controls(dapm, tabla_dapm_aif_in_widgets,
+				  ARRAY_SIZE(tabla_dapm_aif_in_widgets));
+
+	snd_soc_dapm_new_controls(dapm, tabla_dapm_aif_out_widgets,
+				  ARRAY_SIZE(tabla_dapm_aif_out_widgets));
+
 	if (TABLA_IS_1_X(control->version))
 		snd_soc_dapm_new_controls(dapm, tabla_1_x_dapm_widgets,
 					  ARRAY_SIZE(tabla_1_x_dapm_widgets));
diff --git a/sound/soc/msm/mpq8064.c b/sound/soc/msm/mpq8064.c
index 391c5f3..6685ce5 100644
--- a/sound/soc/msm/mpq8064.c
+++ b/sound/soc/msm/mpq8064.c
@@ -850,7 +850,7 @@
 static void msm_mi2s_shutdown(struct snd_pcm_substream *substream)
 {
 	if (mi2s_bit_clk) {
-		clk_disable(mi2s_bit_clk);
+		clk_disable_unprepare(mi2s_bit_clk);
 		clk_put(mi2s_bit_clk);
 		mi2s_bit_clk = NULL;
 	}
@@ -892,7 +892,7 @@
 	if (IS_ERR(mi2s_bit_clk))
 		return PTR_ERR(mi2s_bit_clk);
 	clk_set_rate(mi2s_bit_clk, 0);
-	ret = clk_enable(mi2s_bit_clk);
+	ret = clk_prepare_enable(mi2s_bit_clk);
 	if (IS_ERR_VALUE(ret)) {
 		pr_err("Unable to enable mi2s_bit_clk\n");
 		clk_put(mi2s_bit_clk);
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
index 2455128..c894921 100644
--- a/sound/soc/msm/msm-compr-q6.c
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -34,6 +34,13 @@
 #include "msm-compr-q6.h"
 #include "msm-pcm-routing.h"
 
+#define COMPRE_CAPTURE_NUM_PERIODS	16
+/* Allocate the worst case frame size for compressed audio */
+#define COMPRE_CAPTURE_HEADER_SIZE	(sizeof(struct snd_compr_audio_info))
+#define COMPRE_CAPTURE_MAX_FRAME_SIZE	(6144)
+#define COMPRE_CAPTURE_PERIOD_SIZE	(COMPRE_CAPTURE_MAX_FRAME_SIZE + \
+					 COMPRE_CAPTURE_HEADER_SIZE)
+
 struct snd_msm {
 	struct msm_audio *prtd;
 	unsigned volume;
@@ -42,6 +49,27 @@
 
 static struct audio_locks the_locks;
 
+static struct snd_pcm_hardware msm_compr_hardware_capture = {
+	.info =		 (SNDRV_PCM_INFO_MMAP |
+				SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				SNDRV_PCM_INFO_MMAP_VALID |
+				SNDRV_PCM_INFO_INTERLEAVED |
+				SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
+	.formats =	      SNDRV_PCM_FMTBIT_S16_LE,
+	.rates =		SNDRV_PCM_RATE_8000_48000,
+	.rate_min =	     8000,
+	.rate_max =	     48000,
+	.channels_min =	 1,
+	.channels_max =	 8,
+	.buffer_bytes_max =
+		COMPRE_CAPTURE_PERIOD_SIZE * COMPRE_CAPTURE_NUM_PERIODS ,
+	.period_bytes_min =	COMPRE_CAPTURE_PERIOD_SIZE,
+	.period_bytes_max = COMPRE_CAPTURE_PERIOD_SIZE,
+	.periods_min =	  COMPRE_CAPTURE_NUM_PERIODS,
+	.periods_max =	  COMPRE_CAPTURE_NUM_PERIODS,
+	.fifo_size =	    0,
+};
+
 static struct snd_pcm_hardware msm_compr_hardware_playback = {
 	.info =		 (SNDRV_PCM_INFO_MMAP |
 				SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -81,7 +109,9 @@
 	struct snd_pcm_substream *substream = prtd->substream;
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct audio_aio_write_param param;
+	struct audio_aio_read_param read_param;
 	struct audio_buffer *buf = NULL;
+	uint32_t *ptrmem = (uint32_t *)payload;
 	int i = 0;
 
 	pr_debug("%s opcode =%08x\n", __func__, opcode);
@@ -138,9 +168,53 @@
 		prtd->cmd_ack = 1;
 		wake_up(&the_locks.eos_wait);
 		break;
+	case ASM_DATA_EVENT_READ_DONE: {
+		pr_debug("ASM_DATA_EVENT_READ_DONE\n");
+		pr_debug("buf = %p, data = 0x%X, *data = %p,\n"
+			 "prtd->pcm_irq_pos = %d\n",
+				prtd->audio_client->port[OUT].buf,
+			 *(uint32_t *)prtd->audio_client->port[OUT].buf->data,
+				prtd->audio_client->port[OUT].buf->data,
+				prtd->pcm_irq_pos);
+
+		memcpy(prtd->audio_client->port[OUT].buf->data +
+			   prtd->pcm_irq_pos, (ptrmem + 2),
+			   COMPRE_CAPTURE_HEADER_SIZE);
+		pr_debug("buf = %p, updated data = 0x%X, *data = %p\n",
+				prtd->audio_client->port[OUT].buf,
+			*(uint32_t *)(prtd->audio_client->port[OUT].buf->data +
+				prtd->pcm_irq_pos),
+				prtd->audio_client->port[OUT].buf->data);
+		if (!atomic_read(&prtd->start))
+			break;
+		pr_debug("frame size=%d, buffer = 0x%X\n", ptrmem[2],
+				ptrmem[1]);
+		if (ptrmem[2] > COMPRE_CAPTURE_MAX_FRAME_SIZE) {
+			pr_err("Frame length exceeded the max length");
+			break;
+		}
+		buf = prtd->audio_client->port[OUT].buf;
+		pr_debug("pcm_irq_pos=%d, buf[0].phys = 0x%X\n",
+				prtd->pcm_irq_pos, (uint32_t)buf[0].phys);
+		read_param.len = prtd->pcm_count - COMPRE_CAPTURE_HEADER_SIZE ;
+		read_param.paddr = (unsigned long)(buf[0].phys) +
+			prtd->pcm_irq_pos + COMPRE_CAPTURE_HEADER_SIZE;
+		prtd->pcm_irq_pos += prtd->pcm_count;
+
+		if (atomic_read(&prtd->start))
+			snd_pcm_period_elapsed(substream);
+
+		q6asm_async_read(prtd->audio_client, &read_param);
+		break;
+	}
 	case APR_BASIC_RSP_RESULT: {
 		switch (payload[0]) {
 		case ASM_SESSION_CMD_RUN: {
+			if (substream->stream
+				!= SNDRV_PCM_STREAM_PLAYBACK) {
+				atomic_set(&prtd->start, 1);
+				break;
+			}
 			if (!atomic_read(&prtd->pending_buffer))
 				break;
 			pr_debug("%s:writing %d bytes"
@@ -230,6 +304,9 @@
 		pr_debug("compressd playback, no need to send"
 			" the decoder params\n");
 		break;
+	case SND_AUDIOCODEC_DTS_PASS_THROUGH:
+		pr_debug("compressd DTS playback,dont send the decoder params\n");
+		break;
 	case SND_AUDIOCODEC_WMA:
 		pr_debug("SND_AUDIOCODEC_WMA\n");
 		memset(&wma_cfg, 0x0, sizeof(struct asm_wma_cfg));
@@ -276,6 +353,16 @@
 		if (ret < 0)
 			pr_err("%s: CMD Format block failed\n", __func__);
 		break;
+	case SND_AUDIOCODEC_DTS:
+	case SND_AUDIOCODEC_DTS_LBR:
+		pr_debug("SND_AUDIOCODEC_DTS\n");
+		ret = q6asm_media_format_block(prtd->audio_client,
+				compr->codec);
+		if (ret < 0) {
+			pr_err("%s: CMD Format block failed\n", __func__);
+			return ret;
+		}
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -286,6 +373,44 @@
 	return 0;
 }
 
+static int msm_compr_capture_prepare(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct compr_audio *compr = runtime->private_data;
+	struct msm_audio *prtd = &compr->prtd;
+	struct audio_buffer *buf = prtd->audio_client->port[OUT].buf;
+	struct audio_aio_read_param read_param;
+	int ret = 0;
+	int i;
+	prtd->pcm_size = snd_pcm_lib_buffer_bytes(substream);
+	prtd->pcm_count = snd_pcm_lib_period_bytes(substream);
+	prtd->pcm_irq_pos = 0;
+
+	/* rate and channels are sent to audio driver */
+	prtd->samp_rate = runtime->rate;
+	prtd->channel_mode = runtime->channels;
+
+	if (prtd->enabled)
+		return ret;
+	read_param.len = prtd->pcm_count - COMPRE_CAPTURE_HEADER_SIZE;
+	pr_debug("%s: Samp_rate = %d, Channel = %d, pcm_size = %d,\n"
+			 "pcm_count = %d, periods = %d\n",
+			 __func__, prtd->samp_rate, prtd->channel_mode,
+			 prtd->pcm_size, prtd->pcm_count, runtime->periods);
+
+	for (i = 0; i < runtime->periods; i++) {
+		read_param.uid = i;
+		read_param.paddr = ((unsigned long)(buf[i].phys) +
+					COMPRE_CAPTURE_HEADER_SIZE);
+		q6asm_async_read(prtd->audio_client, &read_param);
+	}
+	prtd->periods = runtime->periods;
+
+	prtd->enabled = 1;
+
+	return ret;
+}
+
 static int msm_compr_trigger(struct snd_pcm_substream *substream, int cmd)
 {
 	int ret = 0;
@@ -298,8 +423,17 @@
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 		prtd->pcm_irq_pos = 0;
-		if (compr->info.codec_param.codec.id ==
-				SND_AUDIOCODEC_AC3_PASS_THROUGH) {
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+			if (compr->info.codec_param.codec.id ==
+				SND_AUDIOCODEC_AC3_PASS_THROUGH ||
+					compr->info.codec_param.codec.id ==
+					SND_AUDIOCODEC_DTS_PASS_THROUGH) {
+				msm_pcm_routing_reg_psthr_stream(
+					soc_prtd->dai_link->be_id,
+					prtd->session_id, substream->stream,
+					1);
+			}
+		} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
 			msm_pcm_routing_reg_psthr_stream(
 				soc_prtd->dai_link->be_id,
 				prtd->session_id, substream->stream, 1);
@@ -312,11 +446,19 @@
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 		pr_debug("SNDRV_PCM_TRIGGER_STOP\n");
-		if (compr->info.codec_param.codec.id ==
-				SND_AUDIOCODEC_AC3_PASS_THROUGH) {
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+			if (compr->info.codec_param.codec.id ==
+					SND_AUDIOCODEC_AC3_PASS_THROUGH) {
+				msm_pcm_routing_reg_psthr_stream(
+					soc_prtd->dai_link->be_id,
+					prtd->session_id, substream->stream,
+					0);
+			}
+		} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
 			msm_pcm_routing_reg_psthr_stream(
 				soc_prtd->dai_link->be_id,
-				prtd->session_id, substream->stream, 0);
+				prtd->session_id, substream->stream,
+				0);
 		}
 		atomic_set(&prtd->start, 0);
 		break;
@@ -349,6 +491,9 @@
 	compr->info.compr_cap.codecs[2] = SND_AUDIOCODEC_AC3_PASS_THROUGH;
 	compr->info.compr_cap.codecs[3] = SND_AUDIOCODEC_WMA;
 	compr->info.compr_cap.codecs[4] = SND_AUDIOCODEC_WMA_PRO;
+	compr->info.compr_cap.codecs[5] = SND_AUDIOCODEC_DTS;
+	compr->info.compr_cap.codecs[6] = SND_AUDIOCODEC_DTS_LBR;
+	compr->info.compr_cap.codecs[7] = SND_AUDIOCODEC_DTS_PASS_THROUGH;
 	/* Add new codecs here */
 }
 
@@ -370,10 +515,6 @@
 		.rampingcurve = SOFT_VOLUME_CURVE_LINEAR,
 	};
 
-	/* Capture path */
-	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
-		return -EINVAL;
-
 	pr_debug("%s\n", __func__);
 	compr = kzalloc(sizeof(struct compr_audio), GFP_KERNEL);
 	if (compr == NULL) {
@@ -389,13 +530,18 @@
 		kfree(prtd);
 		return -ENOMEM;
 	}
-	runtime->hw = msm_compr_hardware_playback;
 
 	pr_info("%s: session ID %d\n", __func__, prtd->audio_client->session);
 
 	prtd->session_id = prtd->audio_client->session;
 
-	prtd->cmd_ack = 1;
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		runtime->hw = msm_compr_hardware_playback;
+		prtd->cmd_ack = 1;
+	} else {
+		runtime->hw = msm_compr_hardware_capture;
+	}
+
 
 	ret = snd_pcm_hw_constraint_list(runtime, 0,
 			SNDRV_PCM_HW_PARAM_RATE,
@@ -410,7 +556,8 @@
 
 	prtd->dsp_cnt = 0;
 	atomic_set(&prtd->pending_buffer, 1);
-	compr->codec = FORMAT_MP3;
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		compr->codec = FORMAT_MP3;
 	populate_codec_list(compr, runtime);
 	runtime->private_data = compr;
 	compressed_audio.prtd =  &compr->prtd;
@@ -473,6 +620,27 @@
 	return 0;
 }
 
+static int msm_compr_capture_close(struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+	struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
+	struct compr_audio *compr = runtime->private_data;
+	struct msm_audio *prtd = &compr->prtd;
+	int dir = OUT;
+
+	pr_debug("%s\n", __func__);
+	atomic_set(&prtd->pending_buffer, 0);
+	q6asm_cmd(prtd->audio_client, CMD_CLOSE);
+	q6asm_audio_client_buf_free_contiguous(dir,
+				prtd->audio_client);
+	msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->be_id,
+				SNDRV_PCM_STREAM_CAPTURE);
+	q6asm_audio_client_free(prtd->audio_client);
+	kfree(prtd);
+
+	return 0;
+}
+
 static int msm_compr_close(struct snd_pcm_substream *substream)
 {
 	int ret = 0;
@@ -480,7 +648,7 @@
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		ret = msm_compr_playback_close(substream);
 	else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
-		ret = EINVAL;
+		ret = msm_compr_capture_close(substream);
 	return ret;
 }
 static int msm_compr_prepare(struct snd_pcm_substream *substream)
@@ -490,7 +658,7 @@
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		ret = msm_compr_playback_prepare(substream);
 	else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
-		ret = EINVAL;
+		ret = msm_compr_capture_prepare(substream);
 	return ret;
 }
 
@@ -504,7 +672,10 @@
 	if (prtd->pcm_irq_pos >= prtd->pcm_size)
 		prtd->pcm_irq_pos = 0;
 
-	pr_debug("pcm_irq_pos = %d\n", prtd->pcm_irq_pos);
+	pr_debug("%s: pcm_irq_pos = %d, pcm_size = %d, sample_bits = %d,\n"
+			 "frame_bits = %d\n", __func__, prtd->pcm_irq_pos,
+			 prtd->pcm_size, runtime->sample_bits,
+			 runtime->frame_bits);
 	return bytes_to_frames(runtime, (prtd->pcm_irq_pos));
 }
 
@@ -546,28 +717,45 @@
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 		dir = IN;
 	else
-		return -EINVAL;
+		dir = OUT;
 
-	switch (compr->info.codec_param.codec.id) {
-	case SND_AUDIOCODEC_AC3_PASS_THROUGH:
-		ret = q6asm_open_write_compressed(prtd->audio_client,
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+		switch (compr->info.codec_param.codec.id) {
+		case SND_AUDIOCODEC_AC3_PASS_THROUGH:
+		case SND_AUDIOCODEC_DTS_PASS_THROUGH:
+			ret = q6asm_open_write_compressed(prtd->audio_client,
 					compr->codec);
+
+			if (ret < 0) {
+				pr_err("%s: Session out open failed\n",
+					__func__);
+				return -ENOMEM;
+			}
+			break;
+		default:
+			ret = q6asm_open_write(prtd->audio_client,
+					compr->codec);
+			if (ret < 0) {
+				pr_err("%s: Session out open failed\n",
+					__func__);
+				return -ENOMEM;
+			}
+			msm_pcm_routing_reg_phy_stream(
+				soc_prtd->dai_link->be_id,
+				prtd->session_id, substream->stream);
+
+			break;
+		}
+	} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+		ret = q6asm_open_read_compressed(prtd->audio_client,
+					compr->codec);
+
 		if (ret < 0) {
 			pr_err("%s: compressed Session out open failed\n",
-					__func__);
+				__func__);
 			return -ENOMEM;
 		}
-		break;
-	default:
-		ret = q6asm_open_write(prtd->audio_client, compr->codec);
-		if (ret < 0) {
-			pr_err("%s: Session out open failed\n", __func__);
-			return -ENOMEM;
-		}
-		msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->be_id,
-			prtd->session_id, substream->stream);
-
-		break;
 	}
 	ret = q6asm_set_io_mode(prtd->audio_client, ASYNC_IO_MODE);
 	if (ret < 0) {
@@ -586,13 +774,17 @@
 	}
 	buf = prtd->audio_client->port[dir].buf;
 
-	pr_debug("%s:buf = %p\n", __func__, buf);
 	dma_buf->dev.type = SNDRV_DMA_TYPE_DEV;
 	dma_buf->dev.dev = substream->pcm->card->dev;
 	dma_buf->private_data = NULL;
 	dma_buf->area = buf[0].data;
 	dma_buf->addr =  buf[0].phys;
 	dma_buf->bytes = runtime->hw.buffer_bytes_max;
+
+	pr_debug("%s: buf[%p]dma_buf->area[%p]dma_buf->addr[%p]\n"
+		 "dma_buf->bytes[%d]\n", __func__,
+		 (void *)buf, (void *)dma_buf->area,
+		 (void *)dma_buf->addr, dma_buf->bytes);
 	if (!dma_buf->area)
 		return -ENOMEM;
 
@@ -674,6 +866,18 @@
 			pr_debug("SND_AUDIOCODEC_WMA_PRO\n");
 			compr->codec = FORMAT_WMA_V10PRO;
 			break;
+		case SND_AUDIOCODEC_DTS_PASS_THROUGH:
+			pr_debug("SND_AUDIOCODEC_DTS_PASS_THROUGH\n");
+			compr->codec = FORMAT_DTS;
+			break;
+		case SND_AUDIOCODEC_DTS:
+			pr_debug("SND_AUDIOCODEC_DTS\n");
+			compr->codec = FORMAT_DTS;
+			break;
+		case SND_AUDIOCODEC_DTS_LBR:
+			pr_debug("SND_AUDIOCODEC_DTS\n");
+			compr->codec = FORMAT_DTS_LBR;
+			break;
 		default:
 			pr_debug("FORMAT_LINEAR_PCM\n");
 			compr->codec = FORMAT_LINEAR_PCM;
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index 8a49f1b..be0951c 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -176,6 +176,17 @@
 			.rate_min =	8000,
 			.rate_max = 48000,
 		},
+		.capture = {
+			.stream_name = "MultiMedia4 Capture",
+			.aif_name = "MM_UL4",
+			.rates = (SNDRV_PCM_RATE_8000_48000|
+					SNDRV_PCM_RATE_KNOT),
+			.formats = SNDRV_PCM_FMTBIT_S16_LE,
+			.channels_min = 1,
+			.channels_max = 8,
+			.rate_min =     8000,
+			.rate_max =	48000,
+		},
 		.ops = &msm_fe_Multimedia_dai_ops,
 		.name = "MultiMedia4",
 	},
diff --git a/sound/soc/msm/msm-dai-q6.c b/sound/soc/msm/msm-dai-q6.c
index b3e5120..147316e 100644
--- a/sound/soc/msm/msm-dai-q6.c
+++ b/sound/soc/msm/msm-dai-q6.c
@@ -40,9 +40,14 @@
 	union afe_port_config port_config;
 };
 
+struct msm_dai_q6_mi2s_dai_config {
+	u16 pdata_mi2s_lines;
+	struct msm_dai_q6_dai_data mi2s_dai_data;
+};
+
 struct msm_dai_q6_mi2s_dai_data {
-	struct msm_dai_q6_dai_data tx_dai;
-	struct msm_dai_q6_dai_data rx_dai;
+	struct msm_dai_q6_mi2s_dai_config tx_dai;
+	struct msm_dai_q6_mi2s_dai_config rx_dai;
 	struct snd_pcm_hw_constraint_list rate_constraint;
 	struct snd_pcm_hw_constraint_list bitwidth_constraint;
 };
@@ -86,8 +91,8 @@
 static const char *mi2s_format[] = {
 	"LPCM",
 	"Compr",
-	"60958-LPCM",
-	"60958-Compr"};
+	"LPCM-60958",
+	"Compr-60958"};
 
 static const struct soc_enum mi2s_config_enum[] = {
 	SOC_ENUM_SINGLE_EXT(4, mi2s_format),
@@ -143,21 +148,63 @@
 {
 	struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
 		dev_get_drvdata(dai->dev);
-	struct msm_dai_q6_dai_data *dai_data =
+	struct msm_dai_q6_mi2s_dai_config *mi2s_dai_config =
 		(substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
 		&mi2s_dai_data->rx_dai : &mi2s_dai_data->tx_dai);
+	struct msm_dai_q6_dai_data *dai_data = &mi2s_dai_config->mi2s_dai_data;
 
 	dai_data->channels = params_channels(params);
 	switch (dai_data->channels) {
-	case 2:
-		dai_data->port_config.mi2s.channel = MSM_AFE_STEREO;
+	case 8:
+	case 7:
+		if (mi2s_dai_config->pdata_mi2s_lines < AFE_I2S_8CHS)
+			goto error_invalid_data;
+		dai_data->port_config.mi2s.line = AFE_I2S_8CHS;
 		break;
+	case 6:
+	case 5:
+		if (mi2s_dai_config->pdata_mi2s_lines < AFE_I2S_6CHS)
+			goto error_invalid_data;
+		dai_data->port_config.mi2s.line = AFE_I2S_6CHS;
+		break;
+	case 4:
+	case 3:
+		if (mi2s_dai_config->pdata_mi2s_lines < AFE_I2S_QUAD01)
+			goto error_invalid_data;
+		if (mi2s_dai_config->pdata_mi2s_lines == AFE_I2S_QUAD23)
+			dai_data->port_config.mi2s.line =
+				mi2s_dai_config->pdata_mi2s_lines;
+		else
+			dai_data->port_config.mi2s.line = AFE_I2S_QUAD01;
+		break;
+	case 2:
 	case 1:
-		dai_data->port_config.mi2s.channel = MSM_AFE_MONO;
+		if (mi2s_dai_config->pdata_mi2s_lines < AFE_I2S_SD0)
+			goto error_invalid_data;
+		switch (mi2s_dai_config->pdata_mi2s_lines) {
+		case AFE_I2S_SD0:
+		case AFE_I2S_SD1:
+		case AFE_I2S_SD2:
+		case AFE_I2S_SD3:
+			dai_data->port_config.mi2s.line =
+				mi2s_dai_config->pdata_mi2s_lines;
+			break;
+		case AFE_I2S_QUAD01:
+		case AFE_I2S_6CHS:
+		case AFE_I2S_8CHS:
+			dai_data->port_config.mi2s.line = AFE_I2S_SD0;
+			break;
+		case AFE_I2S_QUAD23:
+			dai_data->port_config.mi2s.line = AFE_I2S_SD2;
+			break;
+		}
+		if (dai_data->channels == 2)
+			dai_data->port_config.mi2s.channel = MSM_AFE_STEREO;
+		else
+			dai_data->port_config.mi2s.channel = MSM_AFE_MONO;
 		break;
 	default:
-		pr_warn("greater than stereo has not been validated");
-		break;
+		goto error_invalid_data;
 	}
 	dai_data->rate = params_rate(params);
 	dai_data->port_config.mi2s.bitwidth = 16;
@@ -166,7 +213,14 @@
 		mi2s_dai_data->rate_constraint.list = &dai_data->rate;
 		mi2s_dai_data->bitwidth_constraint.list = &dai_data->bitwidth;
 	}
+
+	pr_debug("%s: dai_data->channels = %d, line = %d\n", __func__,
+			dai_data->channels, dai_data->port_config.mi2s.line);
 	return 0;
+error_invalid_data:
+	pr_err("%s: dai_data->channels = %d, line = %d\n", __func__,
+			 dai_data->channels, dai_data->port_config.mi2s.line);
+	return -EINVAL;
 }
 
 static int msm_dai_q6_mi2s_get_lineconfig(u16 sd_lines, u16 *config_ptr,
@@ -276,7 +330,9 @@
 	}
 
 	if (ch_cnt) {
-		dai_data->rx_dai.port_config.mi2s.line = sdline_config;
+		dai_data->rx_dai.mi2s_dai_data.port_config.mi2s.line =
+			sdline_config;
+		dai_data->rx_dai.pdata_mi2s_lines = sdline_config;
 		dai_driver->playback.channels_min = 1;
 		dai_driver->playback.channels_max = ch_cnt << 1;
 	} else {
@@ -292,7 +348,9 @@
 	}
 
 	if (ch_cnt) {
-		dai_data->tx_dai.port_config.mi2s.line = sdline_config;
+		dai_data->tx_dai.mi2s_dai_data.port_config.mi2s.line =
+			sdline_config;
+		dai_data->tx_dai.pdata_mi2s_lines = sdline_config;
 		dai_driver->capture.channels_min = 1;
 		dai_driver->capture.channels_max = ch_cnt << 1;
 	} else {
@@ -301,8 +359,8 @@
 	}
 
 	dev_info(&pdev->dev, "%s: playback sdline %x capture sdline %x\n",
-		 __func__, dai_data->rx_dai.port_config.mi2s.line,
-		 dai_data->tx_dai.port_config.mi2s.line);
+		 __func__, dai_data->rx_dai.pdata_mi2s_lines,
+		 dai_data->tx_dai.pdata_mi2s_lines);
 	dev_info(&pdev->dev, "%s: playback ch_max %d capture ch_mx %d\n",
 		 __func__, dai_driver->playback.channels_max,
 		 dai_driver->capture.channels_max);
@@ -315,8 +373,10 @@
 	struct msm_dai_q6_mi2s_dai_data *mi2s_dai_data =
 	dev_get_drvdata(dai->dev);
 
-	if (test_bit(STATUS_PORT_STARTED, mi2s_dai_data->rx_dai.status_mask) ||
-	    test_bit(STATUS_PORT_STARTED, mi2s_dai_data->rx_dai.status_mask)) {
+	if (test_bit(STATUS_PORT_STARTED,
+		mi2s_dai_data->rx_dai.mi2s_dai_data.status_mask) ||
+	    test_bit(STATUS_PORT_STARTED,
+		mi2s_dai_data->tx_dai.mi2s_dai_data.status_mask)) {
 		dev_err(dai->dev, "%s: err chg i2s mode while dai running",
 			__func__);
 		return -EPERM;
@@ -324,12 +384,12 @@
 
 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 	case SND_SOC_DAIFMT_CBS_CFS:
-		mi2s_dai_data->rx_dai.port_config.mi2s.ws = 1;
-		mi2s_dai_data->tx_dai.port_config.mi2s.ws = 1;
+		mi2s_dai_data->rx_dai.mi2s_dai_data.port_config.mi2s.ws = 1;
+		mi2s_dai_data->tx_dai.mi2s_dai_data.port_config.mi2s.ws = 1;
 		break;
 	case SND_SOC_DAIFMT_CBM_CFM:
-		mi2s_dai_data->rx_dai.port_config.mi2s.ws = 0;
-		mi2s_dai_data->tx_dai.port_config.mi2s.ws = 0;
+		mi2s_dai_data->rx_dai.mi2s_dai_data.port_config.mi2s.ws = 0;
+		mi2s_dai_data->tx_dai.mi2s_dai_data.port_config.mi2s.ws = 0;
 		break;
 	default:
 		return -EINVAL;
@@ -345,7 +405,8 @@
 		dev_get_drvdata(dai->dev);
 	struct msm_dai_q6_dai_data *dai_data =
 		(substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
-		&mi2s_dai_data->rx_dai : &mi2s_dai_data->tx_dai);
+		 &mi2s_dai_data->rx_dai.mi2s_dai_data :
+		 &mi2s_dai_data->tx_dai.mi2s_dai_data);
 	int rc = 0;
 
 	if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
@@ -364,7 +425,8 @@
 		dev_get_drvdata(dai->dev);
 	struct msm_dai_q6_dai_data *dai_data =
 		(substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
-		&mi2s_dai_data->rx_dai : &mi2s_dai_data->tx_dai);
+		 &mi2s_dai_data->rx_dai.mi2s_dai_data :
+		 &mi2s_dai_data->tx_dai.mi2s_dai_data);
 	u16 port_id = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
 		MI2S_RX : MI2S_TX);
 	int rc = 0;
@@ -406,7 +468,8 @@
 		dev_get_drvdata(dai->dev);
 	struct msm_dai_q6_dai_data *dai_data =
 		(substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
-		&mi2s_dai_data->rx_dai : &mi2s_dai_data->tx_dai);
+		 &mi2s_dai_data->rx_dai.mi2s_dai_data :
+		 &mi2s_dai_data->tx_dai.mi2s_dai_data);
 	u16 port_id = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
 		MI2S_RX : MI2S_TX);
 	int rc = 0;
@@ -418,8 +481,10 @@
 		clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
 	}
 
-	if (!test_bit(STATUS_PORT_STARTED, mi2s_dai_data->rx_dai.status_mask) &&
-	    !test_bit(STATUS_PORT_STARTED, mi2s_dai_data->rx_dai.status_mask)) {
+	if (!test_bit(STATUS_PORT_STARTED,
+			mi2s_dai_data->rx_dai.mi2s_dai_data.status_mask) &&
+	    !test_bit(STATUS_PORT_STARTED,
+			mi2s_dai_data->rx_dai.mi2s_dai_data.status_mask)) {
 		mi2s_dai_data->rate_constraint.list = NULL;
 		mi2s_dai_data->bitwidth_constraint.list = NULL;
 	}
@@ -1268,9 +1333,9 @@
 	struct snd_kcontrol *kcontrol = NULL;
 	int rc = 0;
 
-	if (mi2s_dai_data->rx_dai.port_config.mi2s.line) {
+	if (mi2s_dai_data->rx_dai.mi2s_dai_data.port_config.mi2s.line) {
 		kcontrol = snd_ctl_new1(&mi2s_config_controls[0],
-					&mi2s_dai_data->rx_dai);
+					&mi2s_dai_data->rx_dai.mi2s_dai_data);
 		rc = snd_ctl_add(dai->card->snd_card, kcontrol);
 
 		if (IS_ERR_VALUE(rc)) {
@@ -1279,10 +1344,10 @@
 		}
 	}
 
-	if (mi2s_dai_data->tx_dai.port_config.mi2s.line) {
+	if (mi2s_dai_data->tx_dai.mi2s_dai_data.port_config.mi2s.line) {
 		rc = snd_ctl_add(dai->card->snd_card,
-				 snd_ctl_new1(&mi2s_config_controls[2],
-					      &mi2s_dai_data->tx_dai));
+				snd_ctl_new1(&mi2s_config_controls[2],
+				&mi2s_dai_data->tx_dai.mi2s_dai_data));
 
 		if (IS_ERR_VALUE(rc)) {
 			if (kcontrol)
@@ -1302,19 +1367,21 @@
 	int rc;
 
 	/* If AFE port is still up, close it */
-	if (test_bit(STATUS_PORT_STARTED, mi2s_dai_data->rx_dai.status_mask)) {
+	if (test_bit(STATUS_PORT_STARTED,
+			mi2s_dai_data->rx_dai.mi2s_dai_data.status_mask)) {
 		rc = afe_close(MI2S_RX); /* can block */
 		if (IS_ERR_VALUE(rc))
 			dev_err(dai->dev, "fail to close MI2S_RX port\n");
 		clear_bit(STATUS_PORT_STARTED,
-			  mi2s_dai_data->rx_dai.status_mask);
+			  mi2s_dai_data->rx_dai.mi2s_dai_data.status_mask);
 	}
-	if (test_bit(STATUS_PORT_STARTED, mi2s_dai_data->tx_dai.status_mask)) {
+	if (test_bit(STATUS_PORT_STARTED,
+			mi2s_dai_data->tx_dai.mi2s_dai_data.status_mask)) {
 		rc = afe_close(MI2S_TX); /* can block */
 		if (IS_ERR_VALUE(rc))
 			dev_err(dai->dev, "fail to close MI2S_TX port\n");
 		clear_bit(STATUS_PORT_STARTED,
-			  mi2s_dai_data->tx_dai.status_mask);
+			  mi2s_dai_data->tx_dai.mi2s_dai_data.status_mask);
 	}
 	kfree(mi2s_dai_data);
 	snd_soc_unregister_dai(dai->dev);
@@ -1966,6 +2033,8 @@
 	return 0;
 
 err_pdata:
+
+	dev_err(&pdev->dev, "fail to msm_dai_q6_mi2s_dev_probe\n");
 	kfree(dai_data);
 rtn:
 	return rc;
diff --git a/sound/soc/msm/msm-pcm-q6.c b/sound/soc/msm/msm-pcm-q6.c
index 39ce436..168cf97 100644
--- a/sound/soc/msm/msm-pcm-q6.c
+++ b/sound/soc/msm/msm-pcm-q6.c
@@ -532,12 +532,15 @@
 	int dir = OUT;
 
 	pr_debug("%s\n", __func__);
-	q6asm_cmd(prtd->audio_client, CMD_CLOSE);
-	q6asm_audio_client_buf_free_contiguous(dir,
+	if (prtd->audio_client) {
+		q6asm_cmd(prtd->audio_client, CMD_CLOSE);
+		q6asm_audio_client_buf_free_contiguous(dir,
 				prtd->audio_client);
+		q6asm_audio_client_free(prtd->audio_client);
+	}
+
 	msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->be_id,
-	SNDRV_PCM_STREAM_CAPTURE);
-	q6asm_audio_client_free(prtd->audio_client);
+		SNDRV_PCM_STREAM_CAPTURE);
 	kfree(prtd);
 
 	return 0;
@@ -638,7 +641,7 @@
 		if (ret < 0) {
 			pr_err("%s: q6asm_open_read failed\n", __func__);
 			q6asm_audio_client_free(prtd->audio_client);
-			kfree(prtd);
+			prtd->audio_client = NULL;
 			return -ENOMEM;
 		}
 	}
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 239c904..387fe44 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -1352,6 +1352,13 @@
 	msm_routing_put_audio_mixer),
 };
 
+
+static const struct snd_kcontrol_new mmul4_mixer_controls[] = {
+	SOC_SINGLE_EXT("MI2S_TX", MSM_BACKEND_DAI_MI2S_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+};
+
 static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = {
 	SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_PRI_I2S_RX,
 	MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer,
@@ -1983,6 +1990,7 @@
 	SND_SOC_DAPM_AIF_IN("VOIP_DL", "VoIP Playback", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("MM_UL1", "MultiMedia1 Capture", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("MM_UL2", "MultiMedia2 Capture", 0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("MM_UL4", "MultiMedia4 Capture", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("CS-VOICE_DL1", "CS-VOICE Playback", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("CS-VOICE_UL1", "CS-VOICE Capture", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_IN("VoLTE_DL", "VoLTE Playback", 0, 0, 0, 0),
@@ -2080,6 +2088,8 @@
 	mmul1_mixer_controls, ARRAY_SIZE(mmul1_mixer_controls)),
 	SND_SOC_DAPM_MIXER("MultiMedia2 Mixer", SND_SOC_NOPM, 0, 0,
 	mmul2_mixer_controls, ARRAY_SIZE(mmul2_mixer_controls)),
+	SND_SOC_DAPM_MIXER("MultiMedia4 Mixer", SND_SOC_NOPM, 0, 0,
+	mmul4_mixer_controls, ARRAY_SIZE(mmul4_mixer_controls)),
 	SND_SOC_DAPM_MIXER("AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
 	auxpcm_rx_mixer_controls, ARRAY_SIZE(auxpcm_rx_mixer_controls)),
 	SND_SOC_DAPM_MIXER("SEC_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
@@ -2247,6 +2257,7 @@
 	{"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"},
 	{"MultiMedia1 Mixer", "MI2S_TX", "MI2S_TX"},
 	{"MultiMedia2 Mixer", "MI2S_TX", "MI2S_TX"},
+	{"MultiMedia4 Mixer", "MI2S_TX", "MI2S_TX"},
 	{"MultiMedia1 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
 	{"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
 	{"MultiMedia1 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"},
@@ -2276,6 +2287,7 @@
 	{"MM_UL1", NULL, "MultiMedia1 Mixer"},
 	{"MultiMedia2 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
 	{"MM_UL2", NULL, "MultiMedia2 Mixer"},
+	{"MM_UL4", NULL, "MultiMedia4 Mixer"},
 
 	{"AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index 50011a1..f39a227 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -737,6 +737,9 @@
 		cnt++;
 	}
 	ac->port[dir].max_buf_cnt = cnt;
+
+	pr_debug("%s ac->port[%d].max_buf_cnt[%d]\n", __func__, dir,
+			 ac->port[dir].max_buf_cnt);
 	mutex_unlock(&ac->cmd_lock);
 	rc = q6asm_memory_map(ac, buf[0].phys, dir, bufsz, cnt);
 	if (rc < 0) {
@@ -857,6 +860,7 @@
 		case ASM_DATA_CMD_MEDIA_FORMAT_UPDATE:
 		case ASM_STREAM_CMD_SET_ENCDEC_PARAM:
 		case ASM_STREAM_CMD_OPEN_WRITE_COMPRESSED:
+		case ASM_STREAM_CMD_OPEN_READ_COMPRESSED:
 			if (atomic_read(&ac->cmd_state)) {
 				atomic_set(&ac->cmd_state, 0);
 				wake_up(&ac->cmd_wait);
@@ -1260,6 +1264,42 @@
 	return -EINVAL;
 }
 
+int q6asm_open_read_compressed(struct audio_client *ac, uint32_t format)
+{
+	int rc = 0x00;
+	struct asm_stream_cmd_open_read_compressed open;
+#ifdef CONFIG_DEBUG_FS
+	in_cont_index = 0;
+#endif
+	if ((ac == NULL) || (ac->apr == NULL)) {
+		pr_err("%s: APR handle NULL\n", __func__);
+		return -EINVAL;
+	}
+	pr_debug("%s:session[%d]", __func__, ac->session);
+
+	q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE);
+	open.hdr.opcode = ASM_STREAM_CMD_OPEN_READ_COMPRESSED;
+	/* hardcoded as following*/
+	open.frame_per_buf = 1;
+	open.uMode = 0;
+
+	rc = apr_send_pkt(ac->apr, (uint32_t *) &open);
+	if (rc < 0) {
+		pr_err("open failed op[0x%x]rc[%d]\n", open.hdr.opcode, rc);
+		goto fail_cmd;
+	}
+	rc = wait_event_timeout(ac->cmd_wait,
+		(atomic_read(&ac->cmd_state) == 0), 5*HZ);
+	if (!rc) {
+		pr_err("%s: timeout. waited for OPEN_READ_COMPRESSED rc[%d]\n",
+				 __func__, rc);
+		goto fail_cmd;
+	}
+	return 0;
+fail_cmd:
+	return -EINVAL;
+}
+
 int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format)
 {
 	int rc = 0x00;
@@ -1289,6 +1329,9 @@
 	case FORMAT_DTS:
 		open.format = DTS;
 		break;
+	case FORMAT_DTS_LBR:
+		open.format = DTS_LBR;
+		break;
 	case FORMAT_AAC:
 		open.format = MPEG4_AAC;
 		break;
@@ -1372,6 +1415,12 @@
 	case FORMAT_MP3:
 		open.format = MP3;
 		break;
+	case FORMAT_DTS:
+		open.format = DTS;
+		break;
+	case FORMAT_DTS_LBR:
+		open.format = DTS_LBR;
+		break;
 	default:
 		pr_err("%s: Invalid format[%d]\n", __func__, format);
 		goto fail_cmd;
@@ -2263,6 +2312,12 @@
 	case FORMAT_MP3:
 		fmt.format = MP3;
 		break;
+	case FORMAT_DTS:
+		fmt.format = DTS;
+		break;
+	case FORMAT_DTS_LBR:
+		fmt.format = DTS_LBR;
+		break;
 	default:
 		pr_err("Invalid format[%d]\n", format);
 		goto fail_cmd;