Merge "tty: n_smux: Add support for ldisc removal during SSR" into msm-3.4
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 8fb7a8e..7930de5 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1849,9 +1849,6 @@
 config ARCH_MEMORY_REMOVE
 	def_bool n
 
-config ARCH_POPULATES_NODE_MAP
-	def_bool n
-
 config ENABLE_DMM
 	def_bool n
 
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 1f2e285..3854403 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -356,6 +356,7 @@
 CONFIG_IMX074_EEPROM=y
 CONFIG_IMX091_EEPROM=y
 CONFIG_MSM_GEMINI=y
+CONFIG_MSM_MERCURY=y
 CONFIG_MSM_CSI20_HEADER=y
 CONFIG_S5K3L1YX=y
 CONFIG_IMX091=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 8c79847..06501ba 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -359,6 +359,7 @@
 CONFIG_IMX074_EEPROM=y
 CONFIG_IMX091_EEPROM=y
 CONFIG_MSM_GEMINI=y
+CONFIG_MSM_MERCURY=y
 CONFIG_MSM_CSI20_HEADER=y
 CONFIG_S5K3L1YX=y
 CONFIG_IMX091=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index 6f4db42..1a6c134 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -51,6 +51,7 @@
 CONFIG_MSM_TZ_LOG=y
 CONFIG_MSM_DIRECT_SCLK_ACCESS=y
 CONFIG_MSM_OCMEM=y
+CONFIG_MSM_OCMEM_LOCAL_POWER_CTRL=y
 CONFIG_MSM_MEMORY_DUMP=y
 CONFIG_MSM_CACHE_ERP=y
 CONFIG_MSM_L1_ERR_PANIC=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index f026a94..5331f2c 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -2327,6 +2327,15 @@
 	  related operations of OCMEM. Both local power management
 	  and RPM assisted power management operations are supported.
 
+config MSM_OCMEM_POWER_DISABLE
+	bool "OCMEM Disable Power Control"
+	depends on MSM_OCMEM_DEBUG
+	help
+	  Disable all OCMEM power management.
+	  This keeps all OCMEM macros turned ON at all times thus
+	  never allowing them to be turned OFF. Both local power
+	  management and RPM assisted power modes are supported.
+
 config MSM_RTB
 	bool "Register tracing"
 	help
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index ea7fb32..4b4e006 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -2277,11 +2277,13 @@
 	&msm8960_device_ebi1_ch0_erp,
 	&msm8960_device_ebi1_ch1_erp,
 	&epm_adc_device,
-	&apq8064_qdss_device,
-	&msm_etb_device,
-	&msm_tpiu_device,
-	&msm_funnel_device,
-	&apq8064_etm_device,
+	&coresight_tpiu_device,
+	&coresight_etb_device,
+	&apq8064_coresight_funnel_device,
+	&coresight_etm0_device,
+	&coresight_etm1_device,
+	&coresight_etm2_device,
+	&coresight_etm3_device,
 	&apq_cpudai_slim_4_rx,
 	&apq_cpudai_slim_4_tx,
 #ifdef CONFIG_MSM_GEMINI
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 0678461..444580f 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -2239,14 +2239,11 @@
 	&msm8930_ion_dev,
 #endif
 	&msm_device_tz_log,
-
-#ifdef CONFIG_MSM_QDSS
-	&msm_qdss_device,
-	&msm_etb_device,
-	&msm_tpiu_device,
-	&msm_funnel_device,
-	&msm_etm_device,
-#endif
+	&coresight_tpiu_device,
+	&coresight_etb_device,
+	&coresight_funnel_device,
+	&coresight_etm0_device,
+	&coresight_etm1_device,
 	&msm_device_dspcrashd_8960,
 	&msm8960_device_watchdog,
 #ifdef MSM8930_PHASE_2
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 25677c3..7d88ea6 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -2664,13 +2664,11 @@
 	&msm8960_rpm_log_device,
 	&msm8960_rpm_stat_device,
 	&msm_device_tz_log,
-#ifdef CONFIG_MSM_QDSS
-	&msm_qdss_device,
-	&msm_etb_device,
-	&msm_tpiu_device,
-	&msm_funnel_device,
-	&msm_etm_device,
-#endif
+	&coresight_tpiu_device,
+	&coresight_etb_device,
+	&coresight_funnel_device,
+	&coresight_etm0_device,
+	&coresight_etm1_device,
 	&msm_device_dspcrashd_8960,
 	&msm8960_device_watchdog,
 	&msm8960_rtb_device,
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 3b715a4..21b6c0a 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -5176,11 +5176,13 @@
 	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("core_clk",		qdss_clk.c,	"coresight-tpiu.0"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,	"coresight-etb.0"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,	"coresight-funnel.0"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,	"coresight-etm.0"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,	"coresight-etm.1"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,	"coresight-etm.2"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,	"coresight-etm.3"),
 
 	CLK_LOOKUP("ebi1_clk",		ebi1_clk.c,		""),
 	CLK_LOOKUP("mmfpb_clk",		mmfpb_clk.c,		""),
@@ -5515,11 +5517,13 @@
 	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("core_clk",		qdss_clk.c,	"coresight-tpiu.0"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,	"coresight-etb.0"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,	"coresight-funnel.0"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,	"coresight-etm.0"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,	"coresight-etm.1"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,	"coresight-etm.2"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,	"coresight-etm.3"),
 
 	CLK_LOOKUP("ebi1_clk",		ebi1_clk.c,		NULL),
 	CLK_LOOKUP("mmfpb_clk",		mmfpb_clk.c,		NULL),
@@ -5861,11 +5865,13 @@
 	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("core_clk",		qdss_clk.c,	"coresight-tpiu.0"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,	"coresight-etb.0"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,	"coresight-funnel.0"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,	"coresight-etm.0"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,	"coresight-etm.1"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,	"coresight-etm.2"),
+	CLK_LOOKUP("core_clk",		qdss_clk.c,	"coresight-etm.3"),
 
 	CLK_LOOKUP("ebi1_clk",		ebi1_clk.c,		NULL),
 	CLK_LOOKUP("mmfpb_clk",		mmfpb_clk.c,		NULL),
diff --git a/arch/arm/mach-msm/clock-8974.c b/arch/arm/mach-msm/clock-8974.c
index 007e63e..b0ee250 100644
--- a/arch/arm/mach-msm/clock-8974.c
+++ b/arch/arm/mach-msm/clock-8974.c
@@ -4972,7 +4972,7 @@
 	CLK_LOOKUP("osr_clk", audio_core_lpaif_quad_osr_clk.c, ""),
 	CLK_LOOKUP("ebit_clk", audio_core_lpaif_quad_ebit_clk.c, ""),
 	CLK_LOOKUP("ibit_clk", audio_core_lpaif_quad_ibit_clk.c, ""),
-	CLK_LOOKUP("core_clk", audio_core_lpaif_pcm0_clk_src.c,
+	CLK_LOOKUP("pcm_clk", audio_core_lpaif_pcm0_clk_src.c,
 						"msm-dai-q6.4106"),
 	CLK_LOOKUP("ebit_clk", audio_core_lpaif_pcm0_ebit_clk.c, ""),
 	CLK_LOOKUP("ibit_clk", audio_core_lpaif_pcm0_ibit_clk.c,
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 792bc1d..90e0089 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -2666,43 +2666,105 @@
 	.resource	= msm_cache_erp_resources,
 };
 
-#define MSM_QDSS_PHYS_BASE		0x01A00000
-#define MSM_ETM_PHYS_BASE		(MSM_QDSS_PHYS_BASE + 0x1C000)
+#define CORESIGHT_PHYS_BASE		0x01A00000
+#define CORESIGHT_FUNNEL_PHYS_BASE	(CORESIGHT_PHYS_BASE + 0x4000)
+#define CORESIGHT_ETM2_PHYS_BASE	(CORESIGHT_PHYS_BASE + 0x1E000)
+#define CORESIGHT_ETM3_PHYS_BASE	(CORESIGHT_PHYS_BASE + 0x1F000)
 
-#define QDSS_SOURCE(src_name, fpm) { .name = src_name, .fport_mask = fpm, }
-
-static struct qdss_source msm_qdss_sources[] = {
-	QDSS_SOURCE("msm_etm", 0x33),
-	QDSS_SOURCE("msm_oxili", 0x80),
-};
-
-static struct msm_qdss_platform_data qdss_pdata = {
-	.src_table = msm_qdss_sources,
-	.size = ARRAY_SIZE(msm_qdss_sources),
-	.afamily = 1,
-};
-
-struct platform_device apq8064_qdss_device = {
-	.name          = "msm_qdss",
-	.id            = -1,
-	.dev           = {
-		.platform_data = &qdss_pdata,
-	},
-};
-
-static struct resource msm_etm_resources[] = {
+static struct resource coresight_funnel_resources[] = {
 	{
-		.start = MSM_ETM_PHYS_BASE,
-		.end   = MSM_ETM_PHYS_BASE + (SZ_4K * 4) - 1,
+		.start = CORESIGHT_FUNNEL_PHYS_BASE,
+		.end   = CORESIGHT_FUNNEL_PHYS_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
 };
 
-struct platform_device apq8064_etm_device = {
-	.name          = "msm_etm",
+static const int coresight_funnel_outports[] = { 0, 1 };
+static const int coresight_funnel_child_ids[] = { 0, 1 };
+static const int coresight_funnel_child_ports[] = { 0, 0 };
+
+static struct coresight_platform_data coresight_funnel_pdata = {
+	.id		= 2,
+	.name		= "coresight-funnel",
+	.nr_inports	= 4,
+	.outports	= coresight_funnel_outports,
+	.child_ids	= coresight_funnel_child_ids,
+	.child_ports	= coresight_funnel_child_ports,
+	.nr_outports	= ARRAY_SIZE(coresight_funnel_outports),
+};
+
+struct platform_device apq8064_coresight_funnel_device = {
+	.name          = "coresight-funnel",
 	.id            = 0,
-	.num_resources = ARRAY_SIZE(msm_etm_resources),
-	.resource      = msm_etm_resources,
+	.num_resources = ARRAY_SIZE(coresight_funnel_resources),
+	.resource      = coresight_funnel_resources,
+	.dev = {
+		.platform_data = &coresight_funnel_pdata,
+	},
+};
+
+static struct resource coresight_etm2_resources[] = {
+	{
+		.start = CORESIGHT_ETM2_PHYS_BASE,
+		.end   = CORESIGHT_ETM2_PHYS_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+static const int coresight_etm2_outports[] = { 0 };
+static const int coresight_etm2_child_ids[] = { 2 };
+static const int coresight_etm2_child_ports[] = { 4 };
+
+static struct coresight_platform_data coresight_etm2_pdata = {
+	.id		= 6,
+	.name		= "coresight-etm2",
+	.nr_inports	= 1,
+	.outports	= coresight_etm2_outports,
+	.child_ids	= coresight_etm2_child_ids,
+	.child_ports	= coresight_etm2_child_ports,
+	.nr_outports	= ARRAY_SIZE(coresight_etm2_outports),
+};
+
+struct platform_device coresight_etm2_device = {
+	.name          = "coresight-etm",
+	.id            = 2,
+	.num_resources = ARRAY_SIZE(coresight_etm2_resources),
+	.resource      = coresight_etm2_resources,
+	.dev = {
+		.platform_data = &coresight_etm2_pdata,
+	},
+};
+
+static struct resource coresight_etm3_resources[] = {
+	{
+		.start = CORESIGHT_ETM3_PHYS_BASE,
+		.end   = CORESIGHT_ETM3_PHYS_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+static const int coresight_etm3_outports[] = { 0 };
+static const int coresight_etm3_child_ids[] = { 2 };
+static const int coresight_etm3_child_ports[] = { 5 };
+
+static struct coresight_platform_data coresight_etm3_pdata = {
+	.id		= 7,
+	.name		= "coresight-etm3",
+	.nr_inports	= 3,
+	.outports	= coresight_etm3_outports,
+	.child_ids	= coresight_etm3_child_ids,
+	.child_ports	= coresight_etm3_child_ports,
+	.nr_outports	= ARRAY_SIZE(coresight_etm3_outports),
+};
+
+struct platform_device coresight_etm3_device = {
+	.name          = "coresight-etm",
+	.id            = 3,
+	.num_resources = ARRAY_SIZE(coresight_etm3_resources),
+	.resource      = coresight_etm3_resources,
+	.dev = {
+		.platform_data = &coresight_etm3_pdata,
+	},
 };
 
 struct msm_iommu_domain_name apq8064_iommu_ctx_names[] = {
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 724eed8..e07301a 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -3457,95 +3457,199 @@
 
 #endif /* CONFIG_MSM_DSPS */
 
-#ifdef CONFIG_MSM_QDSS
+#define CORESIGHT_PHYS_BASE		0x01A00000
+#define CORESIGHT_TPIU_PHYS_BASE	(CORESIGHT_PHYS_BASE + 0x3000)
+#define CORESIGHT_ETB_PHYS_BASE		(CORESIGHT_PHYS_BASE + 0x1000)
+#define CORESIGHT_FUNNEL_PHYS_BASE	(CORESIGHT_PHYS_BASE + 0x4000)
+#define CORESIGHT_STM_PHYS_BASE		(CORESIGHT_PHYS_BASE + 0x6000)
+#define CORESIGHT_ETM0_PHYS_BASE	(CORESIGHT_PHYS_BASE + 0x1C000)
+#define CORESIGHT_ETM1_PHYS_BASE	(CORESIGHT_PHYS_BASE + 0x1D000)
 
-#define MSM_QDSS_PHYS_BASE		0x01A00000
-#define MSM_ETB_PHYS_BASE		(MSM_QDSS_PHYS_BASE + 0x1000)
-#define MSM_TPIU_PHYS_BASE		(MSM_QDSS_PHYS_BASE + 0x3000)
-#define MSM_FUNNEL_PHYS_BASE		(MSM_QDSS_PHYS_BASE + 0x4000)
-#define MSM_ETM_PHYS_BASE		(MSM_QDSS_PHYS_BASE + 0x1C000)
+#define CORESIGHT_STM_CHANNEL_PHYS_BASE	(0x14000000 + 0x280000)
 
-#define QDSS_SOURCE(src_name, fpm) { .name = src_name, .fport_mask = fpm, }
-
-static struct qdss_source msm_qdss_sources[] = {
-	QDSS_SOURCE("msm_etm", 0x3),
-};
-
-static struct msm_qdss_platform_data qdss_pdata = {
-	.src_table = msm_qdss_sources,
-	.size = ARRAY_SIZE(msm_qdss_sources),
-	.afamily = 1,
-};
-
-struct platform_device msm_qdss_device = {
-	.name          = "msm_qdss",
-	.id            = -1,
-	.dev           = {
-		.platform_data = &qdss_pdata,
-	},
-};
-
-static struct resource msm_etb_resources[] = {
+static struct resource coresight_tpiu_resources[] = {
 	{
-		.start = MSM_ETB_PHYS_BASE,
-		.end   = MSM_ETB_PHYS_BASE + SZ_4K - 1,
+		.start = CORESIGHT_TPIU_PHYS_BASE,
+		.end   = CORESIGHT_TPIU_PHYS_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
 };
 
-struct platform_device msm_etb_device = {
-	.name          = "msm_etb",
-	.id            = 0,
-	.num_resources = ARRAY_SIZE(msm_etb_resources),
-	.resource      = msm_etb_resources,
+static struct coresight_platform_data coresight_tpiu_pdata = {
+	.id		= 0,
+	.name		= "coresight-tpiu",
+	.nr_inports	= 1,
+	.nr_outports	= 0,
 };
 
-static struct resource msm_tpiu_resources[] = {
+struct platform_device coresight_tpiu_device = {
+	.name          = "coresight-tpiu",
+	.id            = 0,
+	.num_resources = ARRAY_SIZE(coresight_tpiu_resources),
+	.resource      = coresight_tpiu_resources,
+	.dev = {
+		.platform_data = &coresight_tpiu_pdata,
+	},
+};
+
+static struct resource coresight_etb_resources[] = {
 	{
-		.start = MSM_TPIU_PHYS_BASE,
-		.end   = MSM_TPIU_PHYS_BASE + SZ_4K - 1,
+		.start = CORESIGHT_ETB_PHYS_BASE,
+		.end   = CORESIGHT_ETB_PHYS_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
 };
 
-struct platform_device msm_tpiu_device = {
-	.name          = "msm_tpiu",
-	.id            = 0,
-	.num_resources = ARRAY_SIZE(msm_tpiu_resources),
-	.resource      = msm_tpiu_resources,
+static struct coresight_platform_data coresight_etb_pdata = {
+	.id		= 1,
+	.name		= "coresight-etb",
+	.nr_inports	= 1,
+	.nr_outports	= 0,
+	.default_sink	= true,
 };
 
-static struct resource msm_funnel_resources[] = {
+struct platform_device coresight_etb_device = {
+	.name          = "coresight-etb",
+	.id            = 0,
+	.num_resources = ARRAY_SIZE(coresight_etb_resources),
+	.resource      = coresight_etb_resources,
+	.dev = {
+		.platform_data = &coresight_etb_pdata,
+	},
+};
+
+static struct resource coresight_funnel_resources[] = {
 	{
-		.start = MSM_FUNNEL_PHYS_BASE,
-		.end   = MSM_FUNNEL_PHYS_BASE + SZ_4K - 1,
+		.start = CORESIGHT_FUNNEL_PHYS_BASE,
+		.end   = CORESIGHT_FUNNEL_PHYS_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
 };
 
-struct platform_device msm_funnel_device = {
-	.name          = "msm_funnel",
-	.id            = 0,
-	.num_resources = ARRAY_SIZE(msm_funnel_resources),
-	.resource      = msm_funnel_resources,
+static const int coresight_funnel_outports[] = { 0, 1 };
+static const int coresight_funnel_child_ids[] = { 0, 1 };
+static const int coresight_funnel_child_ports[] = { 0, 0 };
+
+static struct coresight_platform_data coresight_funnel_pdata = {
+	.id		= 2,
+	.name		= "coresight-funnel",
+	.nr_inports	= 4,
+	.outports	= coresight_funnel_outports,
+	.child_ids	= coresight_funnel_child_ids,
+	.child_ports	= coresight_funnel_child_ports,
+	.nr_outports	= ARRAY_SIZE(coresight_funnel_outports),
 };
 
-static struct resource msm_etm_resources[] = {
+struct platform_device coresight_funnel_device = {
+	.name          = "coresight-funnel",
+	.id            = 0,
+	.num_resources = ARRAY_SIZE(coresight_funnel_resources),
+	.resource      = coresight_funnel_resources,
+	.dev = {
+		.platform_data = &coresight_funnel_pdata,
+	},
+};
+
+static struct resource coresight_stm_resources[] = {
 	{
-		.start = MSM_ETM_PHYS_BASE,
-		.end   = MSM_ETM_PHYS_BASE + (SZ_4K * 2) - 1,
+		.start = CORESIGHT_STM_PHYS_BASE,
+		.end   = CORESIGHT_STM_PHYS_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = CORESIGHT_STM_CHANNEL_PHYS_BASE,
+		.end   = CORESIGHT_STM_CHANNEL_PHYS_BASE + SZ_1M + SZ_512K - 1,
 		.flags = IORESOURCE_MEM,
 	},
 };
 
-struct platform_device msm_etm_device = {
-	.name          = "msm_etm",
-	.id            = 0,
-	.num_resources = ARRAY_SIZE(msm_etm_resources),
-	.resource      = msm_etm_resources,
+static const int coresight_stm_outports[] = { 0 };
+static const int coresight_stm_child_ids[] = { 2 };
+static const int coresight_stm_child_ports[] = { 2 };
+
+static struct coresight_platform_data coresight_stm_pdata = {
+	.id		= 3,
+	.name		= "coresight-stm",
+	.nr_inports	= 0,
+	.outports	= coresight_stm_outports,
+	.child_ids	= coresight_stm_child_ids,
+	.child_ports	= coresight_stm_child_ports,
+	.nr_outports	= ARRAY_SIZE(coresight_stm_outports),
 };
 
-#endif
+struct platform_device coresight_stm_device = {
+	.name          = "coresight-stm",
+	.id            = 0,
+	.num_resources = ARRAY_SIZE(coresight_stm_resources),
+	.resource      = coresight_stm_resources,
+	.dev = {
+		.platform_data = &coresight_stm_pdata,
+	},
+};
+
+static struct resource coresight_etm0_resources[] = {
+	{
+		.start = CORESIGHT_ETM0_PHYS_BASE,
+		.end   = CORESIGHT_ETM0_PHYS_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+static const int coresight_etm0_outports[] = { 0 };
+static const int coresight_etm0_child_ids[] = { 2 };
+static const int coresight_etm0_child_ports[] = { 0 };
+
+static struct coresight_platform_data coresight_etm0_pdata = {
+	.id		= 4,
+	.name		= "coresight-etm0",
+	.nr_inports	= 0,
+	.outports	= coresight_etm0_outports,
+	.child_ids	= coresight_etm0_child_ids,
+	.child_ports	= coresight_etm0_child_ports,
+	.nr_outports	= ARRAY_SIZE(coresight_etm0_outports),
+};
+
+struct platform_device coresight_etm0_device = {
+	.name          = "coresight-etm",
+	.id            = 0,
+	.num_resources = ARRAY_SIZE(coresight_etm0_resources),
+	.resource      = coresight_etm0_resources,
+	.dev = {
+		.platform_data = &coresight_etm0_pdata,
+	},
+};
+
+static struct resource coresight_etm1_resources[] = {
+	{
+		.start = CORESIGHT_ETM1_PHYS_BASE,
+		.end   = CORESIGHT_ETM1_PHYS_BASE + SZ_4K - 1,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+static const int coresight_etm1_outports[] = { 0 };
+static const int coresight_etm1_child_ids[] = { 2 };
+static const int coresight_etm1_child_ports[] = { 1 };
+
+static struct coresight_platform_data coresight_etm1_pdata = {
+	.id		= 5,
+	.name		= "coresight-etm1",
+	.nr_inports	= 0,
+	.outports	= coresight_etm1_outports,
+	.child_ids	= coresight_etm1_child_ids,
+	.child_ports	= coresight_etm1_child_ports,
+	.nr_outports	= ARRAY_SIZE(coresight_etm1_outports),
+};
+
+struct platform_device coresight_etm1_device = {
+	.name          = "coresight-etm",
+	.id            = 1,
+	.num_resources = ARRAY_SIZE(coresight_etm1_resources),
+	.resource      = coresight_etm1_resources,
+	.dev = {
+		.platform_data = &coresight_etm1_pdata,
+	},
+};
 
 static struct resource msm_ebi1_ch0_erp_resources[] = {
 	{
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 84fe195..6726e60 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -363,13 +363,14 @@
 extern struct platform_device msm9615_device_watchdog;
 extern struct platform_device fsm9xxx_device_watchdog;
 
-extern struct platform_device apq8064_qdss_device;
-extern struct platform_device msm_qdss_device;
-extern struct platform_device msm_etb_device;
-extern struct platform_device msm_tpiu_device;
-extern struct platform_device msm_funnel_device;
-extern struct platform_device msm_etm_device;
-extern struct platform_device apq8064_etm_device;
+extern struct platform_device coresight_tpiu_device;
+extern struct platform_device coresight_etb_device;
+extern struct platform_device coresight_funnel_device;
+extern struct platform_device apq8064_coresight_funnel_device;
+extern struct platform_device coresight_etm0_device;
+extern struct platform_device coresight_etm1_device;
+extern struct platform_device coresight_etm2_device;
+extern struct platform_device coresight_etm3_device;
 #endif
 
 extern struct platform_device msm_bus_8064_apps_fabric;
diff --git a/arch/arm/mach-msm/hotplug.c b/arch/arm/mach-msm/hotplug.c
index f8324ce..d1d9f4b 100644
--- a/arch/arm/mach-msm/hotplug.c
+++ b/arch/arm/mach-msm/hotplug.c
@@ -54,8 +54,8 @@
 			 * OK, proper wakeup, we're done
 			 */
 			pen_release = -1;
-			dmac_flush_range((void *)&pen_release,
-				(void *)(&pen_release + sizeof(pen_release)));
+			dmac_flush_range((char *)&pen_release,
+				(char *)&pen_release + sizeof(pen_release));
 			break;
 		}
 
@@ -67,8 +67,8 @@
 		 * possible, since we are currently running incoherently, and
 		 * therefore cannot safely call printk() or anything else
 		 */
-		dmac_inv_range((void *)&pen_release,
-			       (void *)(&pen_release + sizeof(pen_release)));
+		dmac_inv_range((char *)&pen_release,
+			       (char *)&pen_release + sizeof(pen_release));
 		pr_debug("CPU%u: spurious wakeup call\n", cpu);
 	}
 }
diff --git a/arch/arm/mach-msm/krait-regulator.c b/arch/arm/mach-msm/krait-regulator.c
index 03a34d6..63b00c2 100644
--- a/arch/arm/mach-msm/krait-regulator.c
+++ b/arch/arm/mach-msm/krait-regulator.c
@@ -269,7 +269,11 @@
 
 static int set_pmic_gang_phases(int phase_count)
 {
-	return msm_spm_apcs_set_phase(phase_count);
+	/*
+	 * TODO : spm writes for phase control,
+	 * pmic phase control is not working yet
+	 */
+	return 0;
 }
 
 static int set_pmic_gang_voltage(int uV)
diff --git a/arch/arm/mach-msm/ocmem_core.c b/arch/arm/mach-msm/ocmem_core.c
index 019f59f..d8cfefc 100644
--- a/arch/arm/mach-msm/ocmem_core.c
+++ b/arch/arm/mach-msm/ocmem_core.c
@@ -383,6 +383,32 @@
 	return 0;
 }
 
+#if defined(CONFIG_MSM_OCMEM_POWER_DISABLE)
+/* Initializes a region to be turned ON in wide mode */
+static int ocmem_region_set_default_state(unsigned int r_num)
+{
+	unsigned m_num = 0;
+
+	mutex_lock(&region_ctrl_lock);
+
+	for (m_num = 0; m_num < num_banks; m_num++) {
+		apply_macro_vote(0, r_num, m_num, MACRO_ON);
+		aggregate_macro_state(r_num, m_num);
+	}
+
+	aggregate_region_state(r_num);
+	commit_region_state(r_num);
+
+	mutex_unlock(&region_ctrl_lock);
+	return 0;
+}
+
+#else
+static int ocmem_region_set_default_state(unsigned int region_num)
+{
+	return 0;
+}
+#endif
 
 #if defined(CONFIG_MSM_OCMEM_POWER_DEBUG)
 
@@ -489,6 +515,15 @@
 	REGION_DEFAULT_OFF -> REGION_DEFAULT_ON
 **/
 
+#if defined(CONFIG_MSM_OCMEM_POWER_DISABLE)
+/* If power management is disabled leave the macro states as is */
+static int switch_power_state(int id, unsigned long offset, unsigned long len,
+			unsigned new_state)
+{
+	return 0;
+}
+
+#else
 static int switch_power_state(int id, unsigned long offset, unsigned long len,
 			unsigned new_state)
 {
@@ -579,6 +614,7 @@
 	WARN_ON(1);
 	return -EINVAL;
 }
+#endif
 
 /* Interfaces invoked from the scheduler */
 int ocmem_memory_off(int id, unsigned long offset, unsigned long len)
@@ -700,6 +736,10 @@
 			goto hw_not_supported;
 		}
 
+		if (ocmem_region_set_default_state(i)) {
+			pr_err("Failed to initialize region %d\n", i);
+			goto hw_not_supported;
+		}
 	}
 	return 0;
 hw_not_supported:
diff --git a/arch/arm/mach-msm/pil-q6v5.c b/arch/arm/mach-msm/pil-q6v5.c
index a362a7e3..d6ad2aa3 100644
--- a/arch/arm/mach-msm/pil-q6v5.c
+++ b/arch/arm/mach-msm/pil-q6v5.c
@@ -30,6 +30,7 @@
 #define QDSP6SS_RESET			0x014
 #define QDSP6SS_GFMUX_CTL		0x020
 #define QDSP6SS_PWR_CTL			0x030
+#define QDSP6SS_CGC_OVERRIDE		0x034
 
 /* AXI Halt Register Offsets */
 #define AXI_HALTREQ			0x0
@@ -39,15 +40,15 @@
 #define HALT_ACK_TIMEOUT_US		100000
 
 /* QDSP6SS_RESET */
+#define Q6SS_STOP_CORE			BIT(0)
 #define Q6SS_CORE_ARES			BIT(1)
-#define Q6SS_ETM_ISDB_ARES		BIT(3)
-#define Q6SS_STOP_CORE			BIT(4)
+#define Q6SS_BUS_ARES_ENA		BIT(2)
 
 /* QDSP6SS_GFMUX_CTL */
 #define Q6SS_CLK_ENA			BIT(1)
 
 /* QDSP6SS_PWR_CTL */
-#define Q6SS_L2DATA_SLP_NRET_N		BIT(0)
+#define Q6SS_L2DATA_SLP_NRET_N		(BIT(0)|BIT(1)|BIT(2))
 #define Q6SS_L2TAG_SLP_NRET_N		BIT(16)
 #define Q6SS_ETB_SLP_NRET_N		BIT(17)
 #define Q6SS_L2DATA_STBY_N		BIT(18)
@@ -55,6 +56,10 @@
 #define Q6SS_CLAMP_IO			BIT(20)
 #define QDSS_BHS_ON			BIT(21)
 
+/* QDSP6SS_CGC_OVERRIDE */
+#define Q6SS_CORE_CLK_EN		BIT(0)
+#define Q6SS_CORE_RCLK_EN		BIT(1)
+
 int pil_q6v5_make_proxy_votes(struct pil_desc *pil)
 {
 	int ret;
@@ -174,7 +179,7 @@
 
 	/* Assert Q6 resets */
 	val = readl_relaxed(drv->reg_base + QDSP6SS_RESET);
-	val = (Q6SS_CORE_ARES | Q6SS_ETM_ISDB_ARES);
+	val = (Q6SS_CORE_ARES | Q6SS_BUS_ARES_ENA);
 	writel_relaxed(val, drv->reg_base + QDSP6SS_RESET);
 
 	/* Kill power at block headswitch (affects LPASS only) */
@@ -191,7 +196,7 @@
 
 	/* Assert resets, stop core */
 	val = readl_relaxed(drv->reg_base + QDSP6SS_RESET);
-	val |= (Q6SS_CORE_ARES | Q6SS_ETM_ISDB_ARES | Q6SS_STOP_CORE);
+	val |= (Q6SS_CORE_ARES | Q6SS_BUS_ARES_ENA | Q6SS_STOP_CORE);
 	writel_relaxed(val, drv->reg_base + QDSP6SS_RESET);
 
 	/* Enable power block headswitch (only affects LPASS) */
@@ -211,9 +216,15 @@
 	writel_relaxed(val, drv->reg_base + QDSP6SS_PWR_CTL);
 
 	/* Bring core out of reset */
-	val = Q6SS_STOP_CORE;
+	val = readl_relaxed(drv->reg_base + QDSP6SS_RESET);
+	val &= ~Q6SS_CORE_ARES;
 	writel_relaxed(val, drv->reg_base + QDSP6SS_RESET);
 
+	/* Disable clock gating for core and rclk */
+	val = readl_relaxed(drv->reg_base + QDSP6SS_CGC_OVERRIDE);
+	val |= Q6SS_CORE_RCLK_EN | Q6SS_CORE_CLK_EN;
+	writel_relaxed(val, drv->reg_base + QDSP6SS_CGC_OVERRIDE);
+
 	/* Turn on core clock */
 	val = readl_relaxed(drv->reg_base + QDSP6SS_GFMUX_CTL);
 	val |= Q6SS_CLK_ENA;
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c
index a11ca95..2749098 100644
--- a/arch/arm/mach-msm/platsmp.c
+++ b/arch/arm/mach-msm/platsmp.c
@@ -205,8 +205,8 @@
 		if (pen_release == -1)
 			break;
 
-		dmac_inv_range((void *)&pen_release,
-			       (void *)(&pen_release+sizeof(pen_release)));
+		dmac_inv_range((char *)&pen_release,
+			       (char *)&pen_release + sizeof(pen_release));
 		udelay(10);
 	}
 
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
index 1092c77..5c1e7ce 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
@@ -20,7 +20,7 @@
 #include <mach/qdsp6v2/audio_acdb.h>
 
 
-#define MAX_NETWORKS		12
+#define MAX_NETWORKS		15
 
 struct sidetone_atomic_cal {
 	atomic_t	enable;
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index b6fb52a..57f41ca 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -250,8 +250,8 @@
 #endif
 }
 
-#ifdef CONFIG_ARCH_POPULATES_NODE_MAP
-static void __init arm_bootmem_free_apnm(unsigned long max_low,
+#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
+static void __init arm_bootmem_free_hmnm(unsigned long max_low,
 	unsigned long max_high)
 {
 	unsigned long max_zone_pfns[MAX_NR_ZONES];
@@ -267,7 +267,7 @@
 		unsigned long start = memblock_region_memory_base_pfn(reg);
 		unsigned long end = memblock_region_memory_end_pfn(reg);
 
-		add_active_range(0, start, end);
+		memblock_set_node(PFN_PHYS(start), PFN_PHYS(end - start), 0);
 	}
 	free_area_init_nodes(max_zone_pfns);
 }
@@ -491,8 +491,8 @@
 	 */
 	sparse_init();
 
-#ifdef CONFIG_ARCH_POPULATES_NODE_MAP
-	arm_bootmem_free_apnm(max_low, max_high);
+#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
+	arm_bootmem_free_hmnm(max_low, max_high);
 #else
 	/*
 	 * Now free the memory - free_area_init_node needs
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 121bf7c9..5c04693 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -4,7 +4,7 @@
  *
  *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
  *  Copyright (C) 2004-2005  Marcel Holtmann <marcel@holtmann.org>
- *  Copyright (c) 2000-2001, 2010-2011, Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2000-2001, 2010-2012, Code Aurora Forum. All rights reserved.
  *
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -51,6 +51,7 @@
 static bool reset = 0;
 
 static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO];
+static void hci_uart_tty_wakeup_action(unsigned long data);
 
 int hci_uart_register_proto(struct hci_uart_proto *p)
 {
@@ -276,6 +277,8 @@
 	tty->receive_room = 65536;
 
 	spin_lock_init(&hu->rx_lock);
+	tasklet_init(&hu->tty_wakeup_task, hci_uart_tty_wakeup_action,
+			 (unsigned long)hu);
 
 	/* Flush any pending characters in the driver and line discipline. */
 
@@ -309,6 +312,8 @@
 		if (hdev)
 			hci_uart_close(hdev);
 
+		tasklet_kill(&hu->tty_wakeup_task);
+
 		if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
 			hu->proto->close(hu);
 			if (hdev) {
@@ -323,6 +328,8 @@
  *
  *    Callback for transmit wakeup. Called when low level
  *    device driver can accept more send data.
+ *    This callback gets called from the isr context so
+ *    schedule the send data operation to tasklet.
  *
  * Arguments:        tty    pointer to associated tty instance data
  * Return Value:    None
@@ -330,12 +337,26 @@
 static void hci_uart_tty_wakeup(struct tty_struct *tty)
 {
 	struct hci_uart *hu = (void *)tty->disc_data;
+	tasklet_schedule(&hu->tty_wakeup_task);
+}
+
+/* hci_uart_tty_wakeup_action()
+ *
+ * Scheduled action to transmit data when low level device
+ * driver can accept more data.
+ */
+static void hci_uart_tty_wakeup_action(unsigned long data)
+{
+	struct hci_uart *hu = (struct hci_uart *)data;
+	struct tty_struct *tty;
 
 	BT_DBG("");
 
 	if (!hu)
 		return;
 
+	tty = hu->tty;
+
 	clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
 
 	if (tty != hu->tty)
diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h
index dc48239..123fc24 100644
--- a/drivers/bluetooth/hci_uart.h
+++ b/drivers/bluetooth/hci_uart.h
@@ -4,7 +4,7 @@
  *
  *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
  *  Copyright (C) 2004-2005  Marcel Holtmann <marcel@holtmann.org>
- *  Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
+ *  Copyright (c) 2000-2001, 2010, 2012 Code Aurora Forum. All rights reserved.
  *
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -66,6 +66,7 @@
 	unsigned long		hdev_flags;
 
 	struct hci_uart_proto	*proto;
+	struct tasklet_struct	tty_wakeup_task;
 	void			*priv;
 
 	struct sk_buff		*tx_skb;
diff --git a/drivers/coresight/coresight-etb.c b/drivers/coresight/coresight-etb.c
index 2bffae5..30f4d0c 100644
--- a/drivers/coresight/coresight-etb.c
+++ b/drivers/coresight/coresight-etb.c
@@ -23,15 +23,28 @@
 #include <linux/uaccess.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
-#include <linux/mutex.h>
+#include <linux/spinlock.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_LOCK(drvdata)						\
+do {									\
+	mb();								\
+	etb_writel(drvdata, 0x0, CORESIGHT_LAR);			\
+} while (0)
+#define ETB_UNLOCK(drvdata)						\
+do {									\
+	etb_writel(drvdata, CORESIGHT_UNLOCK, CORESIGHT_LAR);		\
+	mb();								\
+} while (0)
+
+
 #define ETB_RAM_DEPTH_REG	(0x004)
 #define ETB_STATUS_REG		(0x00C)
 #define ETB_RAM_READ_DATA_REG	(0x010)
@@ -55,37 +68,27 @@
 #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;
+	void __iomem		*base;
+	struct device		*dev;
+	struct coresight_device	*csdev;
+	struct miscdevice	miscdev;
+	struct clk		*clk;
+	spinlock_t		spinlock;
+	bool			reading;
+	atomic_t		in_use;
+	uint8_t			*buf;
+	bool			enable;
+	uint32_t		trigger_cntr;
 };
 
-static struct etb_drvdata *drvdata;
 
-static void __etb_enable(void)
+static void __etb_enable(struct etb_drvdata *drvdata)
 {
 	int i;
 
-	ETB_UNLOCK();
+	ETB_UNLOCK(drvdata);
 
 	etb_writel(drvdata, 0x0, ETB_RAM_WRITE_POINTER);
 	for (i = 0; i < ETB_SIZE_WORDS; i++)
@@ -98,11 +101,12 @@
 	etb_writel(drvdata, BIT(13) | BIT(0), ETB_FFCR);
 	etb_writel(drvdata, BIT(0), ETB_CTL_REG);
 
-	ETB_LOCK();
+	ETB_LOCK(drvdata);
 }
 
-int etb_enable(void)
+static int etb_enable(struct coresight_device *csdev)
 {
+	struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 	int ret;
 	unsigned long flags;
 
@@ -111,25 +115,24 @@
 		return ret;
 
 	spin_lock_irqsave(&drvdata->spinlock, flags);
-	__etb_enable();
-	drvdata->enabled = true;
-	dev_info(drvdata->dev, "ETB enabled\n");
+	__etb_enable(drvdata);
+	drvdata->enable = true;
 	spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
+	dev_info(drvdata->dev, "ETB enabled\n");
 	return 0;
 }
 
-static void __etb_disable(void)
+static void __etb_disable(struct etb_drvdata *drvdata)
 {
 	int count;
 	uint32_t ffcr;
 
-	ETB_UNLOCK();
+	ETB_UNLOCK(drvdata);
 
 	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);
@@ -137,30 +140,16 @@
 	     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();
+	ETB_LOCK(drvdata);
 }
 
-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)
+static void __etb_dump(struct etb_drvdata *drvdata)
 {
 	int i;
 	uint8_t *buf_ptr;
@@ -170,7 +159,7 @@
 	uint32_t frame_off;
 	uint32_t frame_endoff;
 
-	ETB_UNLOCK();
+	ETB_UNLOCK(drvdata);
 
 	read_ptr = etb_readl(drvdata, ETB_RAM_READ_POINTER);
 	write_ptr = etb_readl(drvdata, ETB_RAM_WRITE_POINTER);
@@ -211,26 +200,54 @@
 
 	etb_writel(drvdata, read_ptr, ETB_RAM_READ_POINTER);
 
-	ETB_LOCK();
+	ETB_LOCK(drvdata);
 }
 
-void etb_dump(void)
+static void etb_disable(struct coresight_device *csdev)
+{
+	struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+	unsigned long flags;
+
+	spin_lock_irqsave(&drvdata->spinlock, flags);
+	__etb_disable(drvdata);
+	__etb_dump(drvdata);
+	drvdata->enable = false;
+	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+
+	clk_disable_unprepare(drvdata->clk);
+
+	dev_info(drvdata->dev, "ETB disabled\n");
+}
+
+static const struct coresight_ops_sink etb_sink_ops = {
+	.enable		= etb_enable,
+	.disable	= etb_disable,
+};
+
+static const struct coresight_ops etb_cs_ops = {
+	.sink_ops	= &etb_sink_ops,
+};
+
+static void etb_dump(struct etb_drvdata *drvdata)
 {
 	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");
+	if (drvdata->enable) {
+		__etb_disable(drvdata);
+		__etb_dump(drvdata);
+		__etb_enable(drvdata);
 	}
 	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+
+	dev_info(drvdata->dev, "ETB dumped\n");
 }
 
 static int etb_open(struct inode *inode, struct file *file)
 {
+	struct etb_drvdata *drvdata = container_of(file->private_data,
+						   struct etb_drvdata, miscdev);
+
 	if (atomic_cmpxchg(&drvdata->in_use, 0, 1))
 		return -EBUSY;
 
@@ -241,8 +258,11 @@
 static ssize_t etb_read(struct file *file, char __user *data,
 				size_t len, loff_t *ppos)
 {
+	struct etb_drvdata *drvdata = container_of(file->private_data,
+						   struct etb_drvdata, miscdev);
+
 	if (drvdata->reading == false) {
-		etb_dump();
+		etb_dump(drvdata);
 		drvdata->reading = true;
 	}
 
@@ -258,38 +278,35 @@
 
 	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;
+	struct etb_drvdata *drvdata = container_of(file->private_data,
+						   struct etb_drvdata, miscdev);
 
+	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,
+	.owner		= THIS_MODULE,
+	.open		= etb_open,
+	.read		= etb_read,
+	.release	= etb_release,
+	.llseek		= no_llseek,
 };
 
 static ssize_t etb_show_trigger_cntr(struct device *dev,
 				     struct device_attribute *attr, char *buf)
 {
+	struct etb_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val = drvdata->trigger_cntr;
+
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -297,6 +314,7 @@
 				      struct device_attribute *attr,
 				      const char *buf, size_t size)
 {
+	struct etb_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -308,61 +326,44 @@
 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;
+static struct attribute *etb_attrs[] = {
+	&dev_attr_trigger_cntr.attr,
+	NULL,
+};
 
-	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;
-	}
+static struct attribute_group etb_attr_grp = {
+	.attrs = etb_attrs,
+};
 
-	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 const struct attribute_group *etb_attr_grps[] = {
+	&etb_attr_grp,
+	NULL,
+};
 
 static int __devinit etb_probe(struct platform_device *pdev)
 {
 	int ret;
+	struct etb_drvdata *drvdata;
 	struct resource *res;
+	struct coresight_desc *desc;
 
 	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;
+	platform_set_drvdata(pdev, drvdata);
 
 	spin_lock_init(&drvdata->spinlock);
 
@@ -376,24 +377,47 @@
 	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;
+		goto err_kzalloc_buf;
 	}
+	drvdata->miscdev.name = ((struct coresight_platform_data *)
+				 (pdev->dev.platform_data))->name;
+	drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
+	drvdata->miscdev.fops = &etb_fops;
+	ret = misc_register(&drvdata->miscdev);
+	if (ret)
+		goto err_misc_register;
 
-	etb_sysfs_init();
+	desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+	if (!desc) {
+		ret = -ENOMEM;
+		goto err_kzalloc_desc;
+	}
+	desc->type = CORESIGHT_DEV_TYPE_SINK;
+	desc->subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_BUFFER;
+	desc->ops = &etb_cs_ops;
+	desc->pdata = pdev->dev.platform_data;
+	desc->dev = &pdev->dev;
+	desc->groups = etb_attr_grps;
+	desc->owner = THIS_MODULE;
+	drvdata->csdev = coresight_register(desc);
+	if (IS_ERR(drvdata->csdev)) {
+		ret = PTR_ERR(drvdata->csdev);
+		goto err_coresight_register;
+	}
+	kfree(desc);
 
 	dev_info(drvdata->dev, "ETB initialized\n");
 	return 0;
-
-err_alloc:
-	misc_deregister(&etb_misc);
-err_misc:
+err_coresight_register:
+	kfree(desc);
+err_kzalloc_desc:
+	misc_deregister(&drvdata->miscdev);
+err_misc_register:
+	kfree(drvdata->buf);
+err_kzalloc_buf:
 err_clk_rate:
 	clk_put(drvdata->clk);
 err_clk_get:
@@ -408,20 +432,19 @@
 
 static int __devexit etb_remove(struct platform_device *pdev)
 {
-	if (drvdata->enabled)
-		etb_disable();
-	etb_sysfs_exit();
+	struct etb_drvdata *drvdata = platform_get_drvdata(pdev);
+
+	coresight_unregister(drvdata->csdev);
+	misc_deregister(&drvdata->miscdev);
 	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"},
+	{.compatible = "coresight-etb"},
 	{}
 };
 
@@ -429,7 +452,7 @@
 	.probe          = etb_probe,
 	.remove         = __devexit_p(etb_remove),
 	.driver         = {
-		.name   = "msm_etb",
+		.name   = "coresight-etb",
 		.owner	= THIS_MODULE,
 		.of_match_table = etb_match,
 	},
diff --git a/drivers/coresight/coresight-etm.c b/drivers/coresight/coresight-etm.c
index b3d2a16..020e542 100644
--- a/drivers/coresight/coresight-etm.c
+++ b/drivers/coresight/coresight-etm.c
@@ -26,6 +26,7 @@
 #include <linux/pm_qos.h>
 #include <linux/sysfs.h>
 #include <linux/stat.h>
+#include <linux/mutex.h>
 #include <linux/clk.h>
 #include <linux/coresight.h>
 #include <asm/sections.h>
@@ -33,10 +34,23 @@
 
 #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)
+
+#define etm_writel(drvdata, val, off)	\
+			__raw_writel((val), drvdata->base + off)
+#define etm_readl(drvdata, off)		\
+			__raw_readl(drvdata->base + off)
+
+#define ETM_LOCK(drvdata)						\
+do {									\
+	mb();								\
+	etm_writel(drvdata, 0x0, CORESIGHT_LAR);			\
+} while (0)
+#define ETM_UNLOCK(drvdata)						\
+do {									\
+	etm_writel(drvdata, CORESIGHT_UNLOCK, CORESIGHT_LAR);		\
+	mb();								\
+} while (0)
+
 
 /*
  * Device registers:
@@ -102,6 +116,7 @@
 #define ETMPDCR			(0x310)
 #define ETMPDSR			(0x314)
 
+
 #define ETM_MAX_ADDR_CMP	(16)
 #define ETM_MAX_CNTR		(4)
 #define ETM_MAX_CTXID_CMP	(3)
@@ -119,7 +134,7 @@
 
 #define ETM_SEQ_STATE_MAX_VAL	(0x2)
 
-enum {
+enum etm_addr_type {
 	ETM_ADDR_TYPE_NONE,
 	ETM_ADDR_TYPE_SINGLE,
 	ETM_ADDR_TYPE_RANGE,
@@ -127,42 +142,25 @@
 	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;
+static int boot_enable = 1;
 #else
-static int etm_boot_enable;
+static int boot_enable;
 #endif
 module_param_named(
-	etm_boot_enable, etm_boot_enable, int, S_IRUGO
+	boot_enable, boot_enable, int, S_IRUGO
 );
 
 struct etm_drvdata {
 	void __iomem			*base;
-	bool				enabled;
+	struct device			*dev;
+	struct coresight_device		*csdev;
+	struct clk			*clk;
+	struct mutex			mutex;
 	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;
+	int				cpu;
 	uint8_t				arch;
 	uint8_t				nr_addr_cmp;
 	uint8_t				nr_cntr;
@@ -200,8 +198,6 @@
 	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):
@@ -218,115 +214,107 @@
  * clock vote in the driver and the save-restore code uses 1. above
  * for its vote
  */
-static void etm_set_pwrdwn(int cpu)
+static void etm_set_pwrdwn(struct etm_drvdata *drvdata)
 {
 	uint32_t etmcr;
 
-	etmcr = etm_readl(drvdata, cpu, ETMCR);
+	etmcr = etm_readl(drvdata, ETMCR);
 	etmcr |= BIT(0);
-	etm_writel(drvdata, cpu, etmcr, ETMCR);
+	etm_writel(drvdata, etmcr, ETMCR);
 }
 
-static void etm_clr_pwrdwn(int cpu)
+static void etm_clr_pwrdwn(struct etm_drvdata *drvdata)
 {
 	uint32_t etmcr;
 
-	etmcr = etm_readl(drvdata, cpu, ETMCR);
+	etmcr = etm_readl(drvdata, ETMCR);
 	etmcr &= ~BIT(0);
-	etm_writel(drvdata, cpu, etmcr, ETMCR);
+	etm_writel(drvdata, etmcr, ETMCR);
 }
 
-static void etm_set_prog(int cpu)
+static void etm_set_prog(struct etm_drvdata *drvdata)
 {
 	uint32_t etmcr;
 	int count;
 
-	etmcr = etm_readl(drvdata, cpu, ETMCR);
+	etmcr = etm_readl(drvdata, ETMCR);
 	etmcr |= BIT(10);
-	etm_writel(drvdata, cpu, etmcr, ETMCR);
-
-	for (count = TIMEOUT_US; BVAL(etm_readl(drvdata, cpu, ETMSR), 1) != 1
+	etm_writel(drvdata, etmcr, ETMCR);
+	for (count = TIMEOUT_US; BVAL(etm_readl(drvdata, ETMSR), 1) != 1
 				&& count > 0; count--)
 		udelay(1);
 	WARN(count == 0, "timeout while setting prog bit, ETMSR: %#x\n",
-	     etm_readl(drvdata, cpu, ETMSR));
+	     etm_readl(drvdata, ETMSR));
 }
 
-static void etm_clr_prog(int cpu)
+static void etm_clr_prog(struct etm_drvdata *drvdata)
 {
 	uint32_t etmcr;
 	int count;
 
-	etmcr = etm_readl(drvdata, cpu, ETMCR);
+	etmcr = etm_readl(drvdata, ETMCR);
 	etmcr &= ~BIT(10);
-	etm_writel(drvdata, cpu, etmcr, ETMCR);
-
-	for (count = TIMEOUT_US; BVAL(etm_readl(drvdata, cpu, ETMSR), 1) != 0
+	etm_writel(drvdata, etmcr, ETMCR);
+	for (count = TIMEOUT_US; BVAL(etm_readl(drvdata, ETMSR), 1) != 0
 				&& count > 0; count--)
 		udelay(1);
 	WARN(count == 0, "timeout while clearing prog bit, ETMSR: %#x\n",
-	     etm_readl(drvdata, cpu, ETMSR));
+	     etm_readl(drvdata, ETMSR));
 }
 
-static void __etm_enable(int cpu)
+static void __etm_enable(struct etm_drvdata *drvdata)
 {
 	int i;
 
-	ETM_UNLOCK(cpu);
+	ETM_UNLOCK(drvdata);
 	/* Vote for ETM power/clock enable */
-	etm_clr_pwrdwn(cpu);
-	etm_set_prog(cpu);
+	etm_clr_pwrdwn(drvdata);
+	etm_set_prog(drvdata);
 
-	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);
+	etm_writel(drvdata, drvdata->ctrl | BIT(10), ETMCR);
+	etm_writel(drvdata, drvdata->trigger_event, ETMTRIGGER);
+	etm_writel(drvdata, drvdata->startstop_ctrl, ETMTSSCR);
+	etm_writel(drvdata, drvdata->enable_event, ETMTEEVR);
+	etm_writel(drvdata, drvdata->enable_ctrl1, ETMTECR1);
+	etm_writel(drvdata, 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));
+		etm_writel(drvdata, drvdata->addr_val[i], ETMACVRn(i));
+		etm_writel(drvdata, 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],
+		etm_writel(drvdata, drvdata->cntr_rld_val[i], ETMCNTRLDVRn(i));
+		etm_writel(drvdata, drvdata->cntr_event[i], ETMCNTENRn(i));
+		etm_writel(drvdata, drvdata->cntr_rld_event[i],
 			   ETMCNTRLDEVRn(i));
-		etm_writel(drvdata, cpu, drvdata->cntr_val[i], ETMCNTVRn(i));
+		etm_writel(drvdata, 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);
+	etm_writel(drvdata, drvdata->seq_12_event, ETMSQ12EVR);
+	etm_writel(drvdata, drvdata->seq_21_event, ETMSQ21EVR);
+	etm_writel(drvdata, drvdata->seq_23_event, ETMSQ23EVR);
+	etm_writel(drvdata, drvdata->seq_31_event, ETMSQ31EVR);
+	etm_writel(drvdata, drvdata->seq_32_event, ETMSQ32EVR);
+	etm_writel(drvdata, drvdata->seq_13_event, ETMSQ13EVR);
+	etm_writel(drvdata, drvdata->seq_curr_state, ETMSQR);
 	for (i = 0; i < drvdata->nr_ext_out; i++)
-		etm_writel(drvdata, cpu, 0x0000406F, ETMEXTOUTEVRn(i));
+		etm_writel(drvdata, 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_writel(drvdata, drvdata->ctxid_val[i], ETMCIDCVRn(i));
+	etm_writel(drvdata, drvdata->ctxid_mask, ETMCIDCMR);
+	etm_writel(drvdata, drvdata->sync_freq, ETMSYNCFR);
+	etm_writel(drvdata, 0x00000000, ETMEXTINSELR);
+	etm_writel(drvdata, drvdata->timestamp_event, ETMTSEVR);
+	etm_writel(drvdata, 0x00000000, ETMAUXCR);
+	etm_writel(drvdata, drvdata->cpu + 1, ETMTRACEIDR);
+	etm_writel(drvdata, 0x00000000, ETMVMIDCVR);
 
-	etm_clr_prog(cpu);
-	ETM_LOCK(cpu);
+	etm_clr_prog(drvdata);
+	ETM_LOCK(drvdata);
 }
 
-static int etm_enable(void)
+static int etm_enable(struct coresight_device *csdev)
 {
-	int ret, cpu;
-
-	if (drvdata->enabled) {
-		dev_err(drvdata->dev, "ETM tracing already enabled\n");
-		ret = -EPERM;
-		goto err;
-	}
+	struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+	int ret;
 
 	wake_lock(&drvdata->wake_lock);
 	/* 1. causes all online cpus to come out of idle PC
@@ -342,52 +330,37 @@
 	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;
+	mutex_lock(&drvdata->mutex);
+	__etm_enable(drvdata);
+	mutex_unlock(&drvdata->mutex);
 
 	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)
+static void __etm_disable(struct etm_drvdata *drvdata)
 {
-	ETM_UNLOCK(cpu);
-	etm_set_prog(cpu);
+	ETM_UNLOCK(drvdata);
+	etm_set_prog(drvdata);
 
 	/* program trace enable to low by using always false event */
-	etm_writel(drvdata, cpu, 0x6F | BIT(14), ETMTEEVR);
+	etm_writel(drvdata, 0x6F | BIT(14), ETMTEEVR);
 
 	/* Vote for ETM power/clock disable */
-	etm_set_pwrdwn(cpu);
-	ETM_LOCK(cpu);
+	etm_set_pwrdwn(drvdata);
+	ETM_LOCK(drvdata);
 }
 
-static int etm_disable(void)
+static void etm_disable(struct coresight_device *csdev)
 {
-	int ret, cpu;
-
-	if (!drvdata->enabled) {
-		dev_err(drvdata->dev, "ETM tracing already disabled\n");
-		ret = -EPERM;
-		goto err;
-	}
+	struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
 	wake_lock(&drvdata->wake_lock);
 	/* 1. causes all online cpus to come out of idle PC
@@ -399,12 +372,9 @@
 	 */
 	pm_qos_update_request(&drvdata->qos_req, 0);
 
-	for_each_online_cpu(cpu)
-		__etm_disable(cpu);
-
-	drvdata->enabled = false;
-
-	qdss_disable(drvdata->src);
+	mutex_lock(&drvdata->mutex);
+	__etm_disable(drvdata);
+	mutex_unlock(&drvdata->mutex);
 
 	clk_disable_unprepare(drvdata->clk);
 
@@ -412,55 +382,23 @@
 	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;
+static const struct coresight_ops_source etm_source_ops = {
+	.enable		= etm_enable,
+	.disable	= etm_disable,
+};
 
-	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 const struct coresight_ops etm_cs_ops = {
+	.source_ops	= &etm_source_ops,
+};
 
 static ssize_t etm_show_nr_addr_cmp(struct device *dev,
 				    struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	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);
@@ -468,7 +406,9 @@
 static ssize_t etm_show_nr_cntr(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	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);
@@ -476,7 +416,9 @@
 static ssize_t etm_show_nr_ctxid_cmp(struct device *dev,
 				     struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	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);
@@ -484,7 +426,9 @@
 static ssize_t etm_show_reset(struct device *dev, struct device_attribute *attr,
 			      char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val = drvdata->reset;
+
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -493,6 +437,7 @@
 			       struct device_attribute *attr, const char *buf,
 			       size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	int i;
 	unsigned long val;
 
@@ -547,13 +492,16 @@
 static ssize_t etm_show_mode(struct device *dev, struct device_attribute *attr,
 			      char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	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)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -581,6 +529,7 @@
 		drvdata->ctrl |= BIT(28);
 	else
 		drvdata->ctrl &= ~BIT(28);
+
 	if (drvdata->mode & ETM_MODE_CTXID)
 		drvdata->ctrl |= (BIT(14) | BIT(15));
 	else
@@ -594,7 +543,9 @@
 static ssize_t etm_show_trigger_event(struct device *dev,
 				      struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val = drvdata->trigger_event;
+
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -602,6 +553,7 @@
 				       struct device_attribute *attr,
 				       const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -616,7 +568,9 @@
 static ssize_t etm_show_enable_event(struct device *dev,
 				     struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val = drvdata->enable_event;
+
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -624,6 +578,7 @@
 				      struct device_attribute *attr,
 				      const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -638,7 +593,9 @@
 static ssize_t etm_show_fifofull_level(struct device *dev,
 				       struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val = drvdata->fifofull_level;
+
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -646,6 +603,7 @@
 					struct device_attribute *attr,
 					const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -660,7 +618,9 @@
 static ssize_t etm_show_addr_idx(struct device *dev,
 				 struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val = drvdata->addr_idx;
+
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -668,6 +628,7 @@
 				  struct device_attribute *attr,
 				  const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -689,6 +650,7 @@
 static ssize_t etm_show_addr_single(struct device *dev,
 				    struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 	uint8_t idx;
 
@@ -709,6 +671,7 @@
 				     struct device_attribute *attr,
 				     const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 	uint8_t idx;
 
@@ -734,6 +697,7 @@
 static ssize_t etm_show_addr_range(struct device *dev,
 				   struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val1, val2;
 	uint8_t idx;
 
@@ -761,6 +725,7 @@
 				    struct device_attribute *attr,
 				    const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val1, val2;
 	uint8_t idx;
 
@@ -798,6 +763,7 @@
 static ssize_t etm_show_addr_start(struct device *dev,
 				   struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 	uint8_t idx;
 
@@ -818,6 +784,7 @@
 				    struct device_attribute *attr,
 				    const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 	uint8_t idx;
 
@@ -845,6 +812,7 @@
 static ssize_t etm_show_addr_stop(struct device *dev,
 				  struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 	uint8_t idx;
 
@@ -865,6 +833,7 @@
 				  struct device_attribute *attr,
 				  const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 	uint8_t idx;
 
@@ -892,6 +861,7 @@
 static ssize_t etm_show_addr_acctype(struct device *dev,
 				     struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	mutex_lock(&drvdata->mutex);
@@ -904,6 +874,7 @@
 				      struct device_attribute *attr,
 				      const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -920,7 +891,9 @@
 static ssize_t etm_show_cntr_idx(struct device *dev,
 				 struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val = drvdata->addr_idx;
+
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -928,6 +901,7 @@
 				  struct device_attribute *attr,
 				  const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -949,7 +923,9 @@
 static ssize_t etm_show_cntr_rld_val(struct device *dev,
 				     struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
+
 	mutex_lock(&drvdata->mutex);
 	val = drvdata->cntr_rld_val[drvdata->cntr_idx];
 	mutex_unlock(&drvdata->mutex);
@@ -960,6 +936,7 @@
 				      struct device_attribute *attr,
 				      const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -976,6 +953,7 @@
 static ssize_t etm_show_cntr_event(struct device *dev,
 				     struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	mutex_lock(&drvdata->mutex);
@@ -988,6 +966,7 @@
 				    struct device_attribute *attr,
 				    const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -1004,6 +983,7 @@
 static ssize_t etm_show_cntr_rld_event(struct device *dev,
 				       struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	mutex_lock(&drvdata->mutex);
@@ -1016,6 +996,7 @@
 					struct device_attribute *attr,
 					const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -1032,6 +1013,7 @@
 static ssize_t etm_show_cntr_val(struct device *dev,
 				 struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	mutex_lock(&drvdata->mutex);
@@ -1044,6 +1026,7 @@
 				  struct device_attribute *attr,
 				  const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -1060,7 +1043,9 @@
 static ssize_t etm_show_seq_12_event(struct device *dev,
 				     struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val = drvdata->seq_12_event;
+
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1068,6 +1053,7 @@
 				      struct device_attribute *attr,
 				      const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -1082,7 +1068,9 @@
 static ssize_t etm_show_seq_21_event(struct device *dev,
 				     struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val = drvdata->seq_21_event;
+
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1090,6 +1078,7 @@
 				      struct device_attribute *attr,
 				      const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -1104,7 +1093,9 @@
 static ssize_t etm_show_seq_23_event(struct device *dev,
 				     struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val = drvdata->seq_23_event;
+
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1112,6 +1103,7 @@
 				      struct device_attribute *attr,
 				      const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -1126,7 +1118,9 @@
 static ssize_t etm_show_seq_31_event(struct device *dev,
 				     struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val = drvdata->seq_31_event;
+
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1134,6 +1128,7 @@
 				      struct device_attribute *attr,
 				      const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -1148,7 +1143,9 @@
 static ssize_t etm_show_seq_32_event(struct device *dev,
 				     struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val = drvdata->seq_32_event;
+
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1156,6 +1153,7 @@
 				      struct device_attribute *attr,
 				      const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -1170,7 +1168,9 @@
 static ssize_t etm_show_seq_13_event(struct device *dev,
 				     struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val = drvdata->seq_13_event;
+
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1178,6 +1178,7 @@
 				      struct device_attribute *attr,
 				      const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -1192,7 +1193,9 @@
 static ssize_t etm_show_seq_curr_state(struct device *dev,
 				       struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val = drvdata->seq_curr_state;
+
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1200,6 +1203,7 @@
 					struct device_attribute *attr,
 					const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -1216,7 +1220,9 @@
 static ssize_t etm_show_ctxid_idx(struct device *dev,
 				  struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val = drvdata->ctxid_idx;
+
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1224,6 +1230,7 @@
 				   struct device_attribute *attr,
 				   const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -1245,6 +1252,7 @@
 static ssize_t etm_show_ctxid_val(struct device *dev,
 				  struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	mutex_lock(&drvdata->mutex);
@@ -1257,6 +1265,7 @@
 				   struct device_attribute *attr,
 				   const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -1273,7 +1282,9 @@
 static ssize_t etm_show_ctxid_mask(struct device *dev,
 				   struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val = drvdata->ctxid_mask;
+
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1281,6 +1292,7 @@
 				    struct device_attribute *attr,
 				    const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -1295,6 +1307,7 @@
 static ssize_t etm_show_sync_freq(struct device *dev,
 				  struct device_attribute *attr, char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val = drvdata->sync_freq;
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
@@ -1303,6 +1316,7 @@
 				   struct device_attribute *attr,
 				   const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -1318,7 +1332,9 @@
 					struct device_attribute *attr,
 					char *buf)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val = drvdata->timestamp_event;
+
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -1326,6 +1342,7 @@
 					 struct device_attribute *attr,
 					 const char *buf, size_t size)
 {
+	struct etm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -1376,39 +1393,18 @@
 	.attrs = etm_attrs,
 };
 
-static int __devinit etm_sysfs_init(void)
+static const struct attribute_group *etm_attr_grps[] = {
+	&etm_attr_grp,
+	NULL,
+};
+
+/* Memory mapped writes to clear os lock not supported */
+static void etm_os_unlock(void *unused)
 {
-	int ret;
+	unsigned long value = 0x0;
 
-	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);
+	asm("mcr p14, 1, %0, c1, c0, 4\n\t" : : "r" (value));
+	asm("isb\n\t");
 }
 
 static bool __devinit etm_arch_supported(uint8_t arch)
@@ -1422,34 +1418,32 @@
 	return true;
 }
 
-static int __devinit etm_init_arch_data(void)
+static int __devinit etm_init_arch_data(struct etm_drvdata *drvdata)
 {
 	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);
+	ETM_UNLOCK(drvdata);
 	/* Vote for ETM power/clock enable */
-	etm_clr_pwrdwn(cpu);
+	etm_clr_pwrdwn(drvdata);
 	/* Set prog bit. It will be set from reset but this is included to
 	 * ensure it is set
 	 */
-	etm_set_prog(cpu);
+	etm_set_prog(drvdata);
 
 	/* find all capabilities */
-	etmidr = etm_readl(drvdata, cpu, ETMIDR);
+	etmidr = etm_readl(drvdata, ETMIDR);
 	drvdata->arch = BMVAL(etmidr, 4, 11);
 	if (etm_arch_supported(drvdata->arch) == false) {
 		ret = -EINVAL;
 		goto err;
 	}
 
-	etmccr = etm_readl(drvdata, cpu, ETMCCR);
+	etmccr = etm_readl(drvdata, 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);
@@ -1457,15 +1451,15 @@
 	drvdata->nr_ctxid_cmp = BMVAL(etmccr, 24, 25);
 
 	/* Vote for ETM power/clock disable */
-	etm_set_pwrdwn(cpu);
-	ETM_LOCK(cpu);
+	etm_set_pwrdwn(drvdata);
+	ETM_LOCK(drvdata);
 
 	return 0;
 err:
 	return ret;
 }
 
-static void __devinit etm_init_default_data(void)
+static void __devinit etm_init_default_data(struct etm_drvdata *drvdata)
 {
 	int i;
 
@@ -1511,37 +1505,34 @@
 static int __devinit etm_probe(struct platform_device *pdev)
 {
 	int ret;
+	struct etm_drvdata *drvdata;
 	struct resource *res;
+	static int etm_count;
+	struct coresight_desc *desc;
 
 	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;
+	platform_set_drvdata(pdev, drvdata);
 
 	mutex_init(&drvdata->mutex);
-	wake_lock_init(&drvdata->wake_lock, WAKE_LOCK_SUSPEND, "msm_etm");
+	wake_lock_init(&drvdata->wake_lock, WAKE_LOCK_SUSPEND, "coresight-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->cpu = etm_count++;
 
 	drvdata->clk = clk_get(drvdata->dev, "core_clk");
 	if (IS_ERR(drvdata->clk)) {
@@ -1552,41 +1543,51 @@
 	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();
+	ret = etm_init_arch_data(drvdata);
 	if (ret)
 		goto err_arch;
-
-	etm_init_default_data();
-
-	ret = etm_sysfs_init();
-	if (ret)
-		goto err_sysfs;
-
-	drvdata->enabled = false;
+	etm_init_default_data(drvdata);
 
 	clk_disable_unprepare(drvdata->clk);
 
+	desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+	if (!desc) {
+		ret = -ENOMEM;
+		goto err_kzalloc_desc;
+	}
+	desc->type = CORESIGHT_DEV_TYPE_SOURCE;
+	desc->subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_PROC;
+	desc->ops = &etm_cs_ops;
+	desc->pdata = pdev->dev.platform_data;
+	desc->dev = &pdev->dev;
+	desc->groups = etm_attr_grps;
+	desc->owner = THIS_MODULE;
+	drvdata->csdev = coresight_register(desc);
+	if (IS_ERR(drvdata->csdev)) {
+		ret = PTR_ERR(drvdata->csdev);
+		goto err_coresight_register;
+	}
+	kfree(desc);
+
 	dev_info(drvdata->dev, "ETM initialized\n");
 
-	if (etm_boot_enable)
-		etm_enable();
+	if (boot_enable)
+		coresight_enable(drvdata->csdev);
 
 	return 0;
-
-err_sysfs:
+err_coresight_register:
+	kfree(desc);
+err_kzalloc_desc:
 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);
@@ -1601,22 +1602,20 @@
 
 static int __devexit etm_remove(struct platform_device *pdev)
 {
-	if (drvdata->enabled)
-		etm_disable();
-	etm_sysfs_exit();
+	struct etm_drvdata *drvdata = platform_get_drvdata(pdev);
+
+	coresight_unregister(drvdata->csdev);
 	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"},
+	{.compatible = "coresight-etm"},
 	{}
 };
 
@@ -1624,7 +1623,7 @@
 	.probe          = etm_probe,
 	.remove         = __devexit_p(etm_remove),
 	.driver         = {
-		.name   = "msm_etm",
+		.name   = "coresight-etm",
 		.owner	= THIS_MODULE,
 		.of_match_table = etm_match,
 	},
diff --git a/drivers/coresight/coresight-funnel.c b/drivers/coresight/coresight-funnel.c
index 79a27f4..333a07c 100644
--- a/drivers/coresight/coresight-funnel.c
+++ b/drivers/coresight/coresight-funnel.c
@@ -24,109 +24,118 @@
 
 #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_writel(drvdata, val, off)	\
+			__raw_writel((val), drvdata->base + off)
+#define funnel_readl(drvdata, off)		\
+			__raw_readl(drvdata->base + off)
 
-
-#define FUNNEL_LOCK(id)							\
+#define FUNNEL_LOCK(drvdata)						\
 do {									\
 	mb();								\
-	funnel_writel(drvdata, id, 0x0, CORESIGHT_LAR);			\
+	funnel_writel(drvdata, 0x0, CORESIGHT_LAR);			\
 } while (0)
-#define FUNNEL_UNLOCK(id)						\
+#define FUNNEL_UNLOCK(drvdata)						\
 do {									\
-	funnel_writel(drvdata, id, CORESIGHT_UNLOCK, CORESIGHT_LAR);	\
+	funnel_writel(drvdata, CORESIGHT_UNLOCK, CORESIGHT_LAR);	\
 	mb();								\
 } while (0)
 
-#define FUNNEL_HOLDTIME_MASK		(0xF00)
-#define FUNNEL_HOLDTIME_SHFT		(0x8)
-#define FUNNEL_HOLDTIME			(0x7 << FUNNEL_HOLDTIME_SHFT)
+
+#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_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;
+	void __iomem		*base;
+	struct device		*dev;
+	struct coresight_device	*csdev;
+	struct clk		*clk;
+	uint32_t		priority;
 };
 
-static struct funnel_drvdata *drvdata;
 
-static void __funnel_enable(uint8_t id, uint32_t port_mask)
+static void __funnel_enable(struct funnel_drvdata *drvdata, int port)
 {
 	uint32_t functl;
 
-	FUNNEL_UNLOCK(id);
+	FUNNEL_UNLOCK(drvdata);
 
-	functl = funnel_readl(drvdata, id, FUNNEL_FUNCTL);
+	functl = funnel_readl(drvdata, 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);
+	functl |= (1 << port);
+	funnel_writel(drvdata, functl, FUNNEL_FUNCTL);
+	funnel_writel(drvdata, drvdata->priority, FUNNEL_PRICTL);
 
-	FUNNEL_LOCK(id);
+	FUNNEL_LOCK(drvdata);
 }
 
-int funnel_enable(uint8_t id, uint32_t port_mask)
+static int funnel_enable(struct coresight_device *csdev, int inport,
+			 int outport)
 {
+	struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 	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);
+	__funnel_enable(drvdata, inport);
 
+	dev_info(drvdata->dev, "FUNNEL inport %d enabled\n", inport);
 	return 0;
 }
 
-static void __funnel_disable(uint8_t id, uint32_t port_mask)
+static void __funnel_disable(struct funnel_drvdata *drvdata, int inport)
 {
 	uint32_t functl;
 
-	FUNNEL_UNLOCK(id);
+	FUNNEL_UNLOCK(drvdata);
 
-	functl = funnel_readl(drvdata, id, FUNNEL_FUNCTL);
-	functl &= ~port_mask;
-	funnel_writel(drvdata, id, functl, FUNNEL_FUNCTL);
+	functl = funnel_readl(drvdata, FUNNEL_FUNCTL);
+	functl &= ~(1 << inport);
+	funnel_writel(drvdata, functl, FUNNEL_FUNCTL);
 
-	FUNNEL_LOCK(id);
+	FUNNEL_LOCK(drvdata);
 }
 
-void funnel_disable(uint8_t id, uint32_t port_mask)
+static void funnel_disable(struct coresight_device *csdev, int inport,
+			   int outport)
 {
-	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);
+	struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+	__funnel_disable(drvdata, inport);
 
 	clk_disable_unprepare(drvdata->clk);
+
+	dev_info(drvdata->dev, "FUNNEL inport %d disabled\n", inport);
 }
 
+static const struct coresight_ops_link funnel_link_ops = {
+	.enable		= funnel_enable,
+	.disable	= funnel_disable,
+};
+
+static const struct coresight_ops funnel_cs_ops = {
+	.link_ops	= &funnel_link_ops,
+};
+
 static ssize_t funnel_show_priority(struct device *dev,
 				    struct device_attribute *attr, char *buf)
 {
+	struct funnel_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val = drvdata->priority;
+
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -134,6 +143,7 @@
 				     struct device_attribute *attr,
 				     const char *buf, size_t size)
 {
+	struct funnel_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -145,63 +155,44 @@
 static DEVICE_ATTR(priority, S_IRUGO | S_IWUSR, funnel_show_priority,
 		   funnel_store_priority);
 
-static int __devinit funnel_sysfs_init(void)
-{
-	int ret;
+static struct attribute *funnel_attrs[] = {
+	&dev_attr_priority.attr,
+	NULL,
+};
 
-	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;
-	}
+static struct attribute_group funnel_attr_grp = {
+	.attrs = funnel_attrs,
+};
 
-	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 const struct attribute_group *funnel_attr_grps[] = {
+	&funnel_attr_grp,
+	NULL,
+};
 
 static int __devinit funnel_probe(struct platform_device *pdev)
 {
 	int ret;
+	struct funnel_drvdata *drvdata;
 	struct resource *res;
+	struct coresight_desc *desc;
 
 	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);
+	platform_set_drvdata(pdev, drvdata);
 
 	drvdata->clk = clk_get(drvdata->dev, "core_clk");
 	if (IS_ERR(drvdata->clk)) {
@@ -213,15 +204,33 @@
 	if (ret)
 		goto err_clk_rate;
 
-	funnel_sysfs_init();
+	desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+	if (!desc) {
+		ret = -ENOMEM;
+		goto err_kzalloc_desc;
+	}
+	desc->type = CORESIGHT_DEV_TYPE_LINK;
+	desc->subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_MERG;
+	desc->ops = &funnel_cs_ops;
+	desc->pdata = pdev->dev.platform_data;
+	desc->dev = &pdev->dev;
+	desc->groups = funnel_attr_grps;
+	desc->owner = THIS_MODULE;
+	drvdata->csdev = coresight_register(desc);
+	if (IS_ERR(drvdata->csdev)) {
+		ret = PTR_ERR(drvdata->csdev);
+		goto err_coresight_register;
+	}
+	kfree(desc);
 
 	dev_info(drvdata->dev, "FUNNEL initialized\n");
 	return 0;
-
+err_coresight_register:
+	kfree(desc);
+err_kzalloc_desc:
 err_clk_rate:
 	clk_put(drvdata->clk);
 err_clk_get:
-	mutex_destroy(&drvdata->mutex);
 	iounmap(drvdata->base);
 err_ioremap:
 err_res:
@@ -233,19 +242,17 @@
 
 static int __devexit funnel_remove(struct platform_device *pdev)
 {
-	if (drvdata->enabled)
-		funnel_disable(0x0, 0xFF);
-	funnel_sysfs_exit();
+	struct funnel_drvdata *drvdata = platform_get_drvdata(pdev);
+
+	coresight_unregister(drvdata->csdev);
 	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"},
+	{.compatible = "coresight-funnel"},
 	{}
 };
 
@@ -253,7 +260,7 @@
 	.probe          = funnel_probe,
 	.remove         = __devexit_p(funnel_remove),
 	.driver         = {
-		.name   = "msm_funnel",
+		.name   = "coresight-funnel",
 		.owner	= THIS_MODULE,
 		.of_match_table = funnel_match,
 	},
diff --git a/drivers/coresight/coresight-priv.h b/drivers/coresight/coresight-priv.h
index dab854c..a6486da 100644
--- a/drivers/coresight/coresight-priv.h
+++ b/drivers/coresight/coresight-priv.h
@@ -15,6 +15,7 @@
 
 #include <linux/bitops.h>
 
+
 /* Coresight management registers (0xF00-0xFCC)
  * 0xFA0 - 0xFA4: Management	registers in PFTv1.0
  *		  Trace		registers in PFTv1.1
@@ -28,6 +29,7 @@
 #define CORESIGHT_DEVID		(0xFC8)
 #define CORESIGHT_DEVTYPE	(0xFCC)
 
+
 #define CORESIGHT_UNLOCK	(0xC5ACCE55)
 
 #define TIMEOUT_US		(100)
@@ -36,13 +38,4 @@
 #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/drivers/coresight/coresight-stm.c b/drivers/coresight/coresight-stm.c
index 6387947..22928aa 100644
--- a/drivers/coresight/coresight-stm.c
+++ b/drivers/coresight/coresight-stm.c
@@ -22,6 +22,7 @@
 #include <linux/miscdevice.h>
 #include <linux/uaccess.h>
 #include <linux/slab.h>
+#include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/coresight.h>
 #include <linux/coresight-stm.h>
@@ -29,15 +30,36 @@
 
 #include "coresight-priv.h"
 
-#define stm_writel(drvdata, val, off)	\
-			__raw_writel((val), drvdata->base + off)
-#define stm_readl(drvdata, val, off)	\
-			__raw_readl(drvdata->base + off)
+
+#define stm_writel(drvdata, val, off)	__raw_writel((val), drvdata->base + off)
+#define stm_readl(drvdata, off)		__raw_readl(drvdata->base + off)
+
+#define STM_LOCK(drvdata)						\
+do {									\
+	mb();								\
+	stm_writel(drvdata, 0x0, CORESIGHT_LAR);			\
+} while (0)
+#define STM_UNLOCK(drvdata)						\
+do {									\
+	stm_writel(drvdata, CORESIGHT_UNLOCK, CORESIGHT_LAR);		\
+	mb();								\
+} while (0)
+
+
+#define STMSPER			(0xE00)
+#define STMSPTER		(0xE20)
+#define STMTCSR			(0xE80)
+#define STMSYNCR		(0xE90)
+
 
 #define NR_STM_CHANNEL		(32)
 #define BYTES_PER_CHANNEL	(256)
+#define STM_TRACE_BUF_SIZE	(1024)
 
-enum {
+#define OST_START_TOKEN		(0x30)
+#define OST_VERSION		(0x1)
+
+enum stm_pkt_type {
 	STM_PKT_TYPE_DATA	= 0x98,
 	STM_PKT_TYPE_FLAG	= 0xE8,
 	STM_PKT_TYPE_TRIG	= 0xF8,
@@ -47,45 +69,25 @@
 	STM_OPTION_MARKED	= 0x10,
 };
 
-#define STM_TRACE_BUF_SIZE	(1024)
-
-#define OST_START_TOKEN		(0x30)
-#define OST_VERSION		(0x1)
-
-#define stm_channel_addr(ch)						\
-				(drvdata->chs.base + (ch * BYTES_PER_CHANNEL))
+#define stm_channel_addr(drvdata, ch)	(drvdata->chs.base +	\
+					(ch * BYTES_PER_CHANNEL))
 #define stm_channel_off(type, opts)	(type & ~opts)
 
-#define STM_LOCK()							\
-do {									\
-	mb();								\
-	stm_writel(drvdata, 0x0, CORESIGHT_LAR);			\
-} while (0)
-#define STM_UNLOCK()							\
-do {									\
-	stm_writel(drvdata, CORESIGHT_UNLOCK, CORESIGHT_LAR);		\
-	mb();								\
-} while (0)
-
-#define STMSPER		(0xE00)
-#define STMSPTER	(0xE20)
-#define STMTCSR		(0xE80)
-#define STMSYNCR	(0xE90)
 
 #ifdef CONFIG_MSM_QDSS_STM_DEFAULT_ENABLE
-static int stm_boot_enable = 1;
+static int boot_enable = 1;
 #else
-static int stm_boot_enable;
+static int boot_enable;
 #endif
 
 module_param_named(
-	stm_boot_enable, stm_boot_enable, int, S_IRUGO
+	boot_enable, boot_enable, int, S_IRUGO
 );
 
-static int stm_boot_nr_channel;
+static int boot_nr_channel;
 
 module_param_named(
-	stm_boot_nr_channel, stm_boot_nr_channel, int, S_IRUGO
+	boot_nr_channel, boot_nr_channel, int, S_IRUGO
 );
 
 struct channel_space {
@@ -95,99 +97,83 @@
 
 struct stm_drvdata {
 	void __iomem		*base;
-	bool			enabled;
-	struct qdss_source	*src;
 	struct device		*dev;
-	struct kobject		*kobj;
+	struct coresight_device	*csdev;
+	struct miscdevice	miscdev;
 	struct clk		*clk;
-	uint32_t		entity;
 	struct channel_space	chs;
+	bool			enable;
+	uint32_t		entity;
 };
 
-static struct stm_drvdata *drvdata;
+static struct stm_drvdata *stmdrvdata;
 
-static void __stm_enable(void)
+
+static void __stm_enable(struct stm_drvdata *drvdata)
 {
-	STM_UNLOCK();
+	STM_UNLOCK(drvdata);
 
 	stm_writel(drvdata, 0x80, STMSYNCR);
 	stm_writel(drvdata, 0xFFFFFFFF, STMSPTER);
 	stm_writel(drvdata, 0xFFFFFFFF, STMSPER);
 	stm_writel(drvdata, 0x30003, STMTCSR);
 
-	STM_LOCK();
+	STM_LOCK(drvdata);
 }
 
-static int stm_enable(void)
+static int stm_enable(struct coresight_device *csdev)
 {
+	struct stm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 	int ret;
 
-	if (drvdata->enabled) {
-		dev_err(drvdata->dev, "STM tracing already enabled\n");
-		ret = -EINVAL;
-		goto err;
-	}
-
 	ret = clk_prepare_enable(drvdata->clk);
 	if (ret)
-		goto err_clk;
+		return ret;
 
-	ret = qdss_enable(drvdata->src);
-	if (ret)
-		goto err_qdss;
-
-	__stm_enable();
-
-	drvdata->enabled = true;
+	__stm_enable(drvdata);
+	drvdata->enable = true;
 
 	dev_info(drvdata->dev, "STM tracing enabled\n");
 	return 0;
-
-err_qdss:
-	clk_disable_unprepare(drvdata->clk);
-err_clk:
-err:
-	return ret;
 }
 
-static void __stm_disable(void)
+static void __stm_disable(struct stm_drvdata *drvdata)
 {
-	STM_UNLOCK();
+	STM_UNLOCK(drvdata);
 
 	stm_writel(drvdata, 0x30000, STMTCSR);
 	stm_writel(drvdata, 0x0, STMSPER);
 	stm_writel(drvdata, 0x0, STMSPTER);
 
-	STM_LOCK();
+	STM_LOCK(drvdata);
 }
 
-static int stm_disable(void)
+static void stm_disable(struct coresight_device *csdev)
 {
-	int ret;
+	struct stm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
-	if (!drvdata->enabled) {
-		dev_err(drvdata->dev, "STM tracing already disabled\n");
-		ret = -EINVAL;
-		goto err;
-	}
-
-	__stm_disable();
-
-	drvdata->enabled = false;
-
-	qdss_disable(drvdata->src);
+	__stm_disable(drvdata);
+	drvdata->enable = false;
+	/* Wait for 100ms so that pending data has been written to HW */
+	msleep(100);
 
 	clk_disable_unprepare(drvdata->clk);
 
 	dev_info(drvdata->dev, "STM tracing disabled\n");
-	return 0;
-
-err:
-	return ret;
 }
 
+static const struct coresight_ops_source stm_source_ops = {
+	.enable		= stm_enable,
+	.disable	= stm_disable,
+};
+
+static const struct coresight_ops stm_cs_ops = {
+	.source_ops	= &stm_source_ops,
+};
+
 static uint32_t stm_channel_alloc(uint32_t off)
 {
+	struct stm_drvdata *drvdata = stmdrvdata;
 	uint32_t ch;
 
 	do {
@@ -201,6 +187,8 @@
 
 static void stm_channel_free(uint32_t ch)
 {
+	struct stm_drvdata *drvdata = stmdrvdata;
+
 	clear_bit(ch, drvdata->chs.bitmap);
 }
 
@@ -301,13 +289,14 @@
 static inline int __stm_trace(uint32_t options, uint8_t entity_id,
 			      uint8_t proto_id, const void *data, uint32_t size)
 {
+	struct stm_drvdata *drvdata = stmdrvdata;
 	int len = 0;
 	uint32_t ch;
 	unsigned long ch_addr;
 
 	/* allocate channel and get the channel address */
 	ch = stm_channel_alloc(0);
-	ch_addr = (unsigned long)stm_channel_addr(ch);
+	ch_addr = (unsigned long)stm_channel_addr(drvdata, ch);
 
 	/* send the ost header */
 	len += stm_trace_ost_header(ch_addr, options, entity_id, proto_id, data,
@@ -344,21 +333,25 @@
 int stm_trace(uint32_t options, uint8_t entity_id, uint8_t proto_id,
 			const void *data, uint32_t size)
 {
+	struct stm_drvdata *drvdata = stmdrvdata;
+
 	/* we don't support sizes more than 24bits (0 to 23) */
-	if (!(drvdata->enabled && (drvdata->entity & entity_id) &&
+	if (!(drvdata && drvdata->enable && (drvdata->entity & entity_id) &&
 	      (size < 0x1000000)))
 		return 0;
 
 	return __stm_trace(options, entity_id, proto_id, data, size);
 }
-EXPORT_SYMBOL(stm_trace);
+EXPORT_SYMBOL_GPL(stm_trace);
 
 static ssize_t stm_write(struct file *file, const char __user *data,
 			 size_t size, loff_t *ppos)
 {
+	struct stm_drvdata *drvdata = container_of(file->private_data,
+						   struct stm_drvdata, miscdev);
 	char *buf;
 
-	if (!drvdata->enabled)
+	if (!drvdata->enable)
 		return -EINVAL;
 
 	if (!(drvdata->entity & OST_ENTITY_DEV_NODE))
@@ -386,49 +379,17 @@
 
 static const struct file_operations stm_fops = {
 	.owner		= THIS_MODULE,
+	.open		= nonseekable_open,
 	.write		= stm_write,
 	.llseek		= no_llseek,
 };
 
-static struct miscdevice stm_misc = {
-	.name		= "msm_stm",
-	.minor		= MISC_DYNAMIC_MINOR,
-	.fops		= &stm_fops,
-};
-
-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 stm_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;
-
-	if (val)
-		ret = stm_enable();
-	else
-		ret = stm_disable();
-
-	if (ret)
-		return ret;
-	return size;
-}
-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)
 {
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val = drvdata->entity;
+
 	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
 }
 
@@ -436,6 +397,7 @@
 				struct device_attribute *attr,
 				const char *buf, size_t size)
 {
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	unsigned long val;
 
 	if (sscanf(buf, "%lx", &val) != 1)
@@ -447,103 +409,72 @@
 static DEVICE_ATTR(entity, S_IRUGO | S_IWUSR, stm_show_entity,
 		   stm_store_entity);
 
-static int __devinit stm_sysfs_init(void)
-{
-	int ret;
+static struct attribute *stm_attrs[] = {
+	&dev_attr_entity.attr,
+	NULL,
+};
 
-	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;
-	}
+static struct attribute_group stm_attr_grp = {
+	.attrs = stm_attrs,
+};
 
-	ret = sysfs_create_file(drvdata->kobj, &dev_attr_enabled.attr);
-	if (ret) {
-		dev_err(drvdata->dev, "failed to create STM sysfs enabled attr\n");
-		goto err_file;
-	}
-
-	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(drvdata->kobj);
-err_create:
-	return ret;
-}
-
-static void __devexit stm_sysfs_exit(void)
-{
-	sysfs_remove_file(drvdata->kobj, &dev_attr_entity.attr);
-	sysfs_remove_file(drvdata->kobj, &dev_attr_enabled.attr);
-	kobject_put(drvdata->kobj);
-}
+static const struct attribute_group *stm_attr_grps[] = {
+	&stm_attr_grp,
+	NULL,
+};
 
 static int __devinit stm_probe(struct platform_device *pdev)
 {
 	int ret;
+	struct stm_drvdata *drvdata;
 	struct resource *res;
 	size_t res_size, bitmap_size;
+	struct coresight_desc *desc;
 
 	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;
 	}
-
 	drvdata->base = ioremap_nocache(res->start, resource_size(res));
 	if (!drvdata->base) {
 		ret = -EINVAL;
 		goto err_ioremap0;
 	}
+	drvdata->dev = &pdev->dev;
+	platform_set_drvdata(pdev, drvdata);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 	if (!res) {
 		ret = -EINVAL;
 		goto err_res1;
 	}
-
-	if (stm_boot_nr_channel) {
-		res_size = min((resource_size_t)(stm_boot_nr_channel *
+	if (boot_nr_channel) {
+		res_size = min((resource_size_t)(boot_nr_channel *
 				  BYTES_PER_CHANNEL), resource_size(res));
-		bitmap_size = stm_boot_nr_channel * sizeof(long);
+		bitmap_size = boot_nr_channel * sizeof(long);
 	} else {
 		res_size = min((resource_size_t)(NR_STM_CHANNEL *
 				 BYTES_PER_CHANNEL), resource_size(res));
 		bitmap_size = NR_STM_CHANNEL * sizeof(long);
 	}
-
 	drvdata->chs.bitmap = kzalloc(bitmap_size, GFP_KERNEL);
 	if (!drvdata->chs.bitmap) {
 		ret = -ENOMEM;
-		goto err_bitmap;
+		goto err_kzalloc_bitmap;
 	}
-
 	drvdata->chs.base = ioremap_nocache(res->start, res_size);
 	if (!drvdata->chs.base) {
 		ret = -EINVAL;
 		goto err_ioremap1;
 	}
-
-	drvdata->dev = &pdev->dev;
-
-	ret = misc_register(&stm_misc);
-	if (ret)
-		goto err_misc;
-
-	drvdata->src = qdss_get("msm_stm");
-	if (IS_ERR(drvdata->src)) {
-		ret = PTR_ERR(drvdata->src);
-		goto err_qdssget;
-	}
+	/* Store the driver data pointer for use in exported functions */
+	stmdrvdata = drvdata;
 
 	drvdata->clk = clk_get(drvdata->dev, "core_clk");
 	if (IS_ERR(drvdata->clk)) {
@@ -555,59 +486,79 @@
 	if (ret)
 		goto err_clk_rate;
 
+	drvdata->miscdev.name = ((struct coresight_platform_data *)
+				 (pdev->dev.platform_data))->name;
+	drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
+	drvdata->miscdev.fops = &stm_fops;
+	ret = misc_register(&drvdata->miscdev);
+	if (ret)
+		goto err_misc_register;
+
 	drvdata->entity = OST_ENTITY_ALL;
 
-	ret = stm_sysfs_init();
-	if (ret)
-		goto err_sysfs;
-
-	if (stm_boot_enable)
-		stm_enable();
+	desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+	if (!desc) {
+		ret = -ENOMEM;
+		goto err_kzalloc_desc;
+	}
+	desc->type = CORESIGHT_DEV_TYPE_SOURCE;
+	desc->subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE;
+	desc->ops = &stm_cs_ops;
+	desc->pdata = pdev->dev.platform_data;
+	desc->dev = &pdev->dev;
+	desc->groups = stm_attr_grps;
+	desc->owner = THIS_MODULE;
+	drvdata->csdev = coresight_register(desc);
+	if (IS_ERR(drvdata->csdev)) {
+		ret = PTR_ERR(drvdata->csdev);
+		goto err_coresight_register;
+	}
+	kfree(desc);
 
 	dev_info(drvdata->dev, "STM initialized\n");
-	return 0;
 
-err_sysfs:
+	if (boot_enable)
+		coresight_enable(drvdata->csdev);
+
+	return 0;
+err_coresight_register:
+	kfree(desc);
+err_kzalloc_desc:
+	misc_deregister(&drvdata->miscdev);
+err_misc_register:
 err_clk_rate:
 	clk_put(drvdata->clk);
 err_clk_get:
-	qdss_put(drvdata->src);
-err_qdssget:
-	misc_deregister(&stm_misc);
-err_misc:
 	iounmap(drvdata->chs.base);
 err_ioremap1:
 	kfree(drvdata->chs.bitmap);
-err_bitmap:
+err_kzalloc_bitmap:
 err_res1:
 	iounmap(drvdata->base);
 err_ioremap0:
 err_res0:
 	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 (drvdata->enabled)
-		stm_disable();
-	stm_sysfs_exit();
+	struct stm_drvdata *drvdata = platform_get_drvdata(pdev);
+
+	coresight_unregister(drvdata->csdev);
+	misc_deregister(&drvdata->miscdev);
 	clk_put(drvdata->clk);
-	qdss_put(drvdata->src);
-	misc_deregister(&stm_misc);
 	iounmap(drvdata->chs.base);
 	kfree(drvdata->chs.bitmap);
 	iounmap(drvdata->base);
 	kfree(drvdata);
-
 	return 0;
 }
 
 static struct of_device_id stm_match[] = {
-	{.compatible = "qcom,msm-stm"},
+	{.compatible = "coresight-stm"},
 	{}
 };
 
@@ -615,7 +566,7 @@
 	.probe          = stm_probe,
 	.remove         = __devexit_p(stm_remove),
 	.driver         = {
-		.name   = "msm_stm",
+		.name   = "coresight-stm",
 		.owner	= THIS_MODULE,
 		.of_match_table = stm_match,
 	},
diff --git a/drivers/coresight/coresight-tpiu.c b/drivers/coresight/coresight-tpiu.c
index c0bcfdd..570eeb2 100644
--- a/drivers/coresight/coresight-tpiu.c
+++ b/drivers/coresight/coresight-tpiu.c
@@ -23,91 +23,129 @@
 
 #include "coresight-priv.h"
 
+
 #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)
-#define TPIU_SUPP_TRIGMODES				(0x100)
-#define TPIU_TRIG_CNTRVAL				(0x104)
-#define TPIU_TRIG_MULT					(0x108)
-#define TPIU_SUPP_TESTPATM				(0x200)
-#define TPIU_CURR_TESTPATM				(0x204)
-#define TPIU_TEST_PATREPCNTR				(0x208)
-#define TPIU_FFSR					(0x300)
-#define TPIU_FFCR					(0x304)
-#define TPIU_FSYNC_CNTR					(0x308)
-#define TPIU_EXTCTL_INPORT				(0x400)
-#define TPIU_EXTCTL_OUTPORT				(0x404)
-#define TPIU_ITTRFLINACK				(0xEE4)
-#define TPIU_ITTRFLIN					(0xEE8)
-#define TPIU_ITATBDATA0					(0xEEC)
-#define TPIU_ITATBCTR2					(0xEF0)
-#define TPIU_ITATBCTR1					(0xEF4)
-#define TPIU_ITATBCTR0					(0xEF8)
-
-
-#define TPIU_LOCK()							\
+#define TPIU_LOCK(drvdata)						\
 do {									\
 	mb();								\
 	tpiu_writel(drvdata, 0x0, CORESIGHT_LAR);			\
 } while (0)
-#define TPIU_UNLOCK()							\
+#define TPIU_UNLOCK(drvdata)						\
 do {									\
 	tpiu_writel(drvdata, CORESIGHT_UNLOCK, CORESIGHT_LAR);		\
 	mb();								\
 } while (0)
 
+
+#define TPIU_SUPP_PORTSZ	(0x000)
+#define TPIU_CURR_PORTSZ	(0x004)
+#define TPIU_SUPP_TRIGMODES	(0x100)
+#define TPIU_TRIG_CNTRVAL	(0x104)
+#define TPIU_TRIG_MULT		(0x108)
+#define TPIU_SUPP_TESTPATM	(0x200)
+#define TPIU_CURR_TESTPATM	(0x204)
+#define TPIU_TEST_PATREPCNTR	(0x208)
+#define TPIU_FFSR		(0x300)
+#define TPIU_FFCR		(0x304)
+#define TPIU_FSYNC_CNTR		(0x308)
+#define TPIU_EXTCTL_INPORT	(0x400)
+#define TPIU_EXTCTL_OUTPORT	(0x404)
+#define TPIU_ITTRFLINACK	(0xEE4)
+#define TPIU_ITTRFLIN		(0xEE8)
+#define TPIU_ITATBDATA0		(0xEEC)
+#define TPIU_ITATBCTR2		(0xEF0)
+#define TPIU_ITATBCTR1		(0xEF4)
+#define TPIU_ITATBCTR0		(0xEF8)
+
+
 struct tpiu_drvdata {
-	void __iomem	*base;
-	bool		enabled;
-	struct device	*dev;
-	struct clk	*clk;
+	void __iomem		*base;
+	struct device		*dev;
+	struct coresight_device	*csdev;
+	struct clk		*clk;
 };
 
-static struct tpiu_drvdata *drvdata;
 
-static void __tpiu_disable(void)
+static void __tpiu_enable(struct tpiu_drvdata *drvdata)
 {
-	TPIU_UNLOCK();
+	TPIU_UNLOCK(drvdata);
+
+	/* TODO: fill this up */
+
+	TPIU_LOCK(drvdata);
+}
+
+static int tpiu_enable(struct coresight_device *csdev)
+{
+	struct tpiu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+	int ret;
+
+	ret = clk_prepare_enable(drvdata->clk);
+	if (ret)
+		return ret;
+
+	__tpiu_enable(drvdata);
+
+	dev_info(drvdata->dev, "TPIU enabled\n");
+	return 0;
+}
+
+static void __tpiu_disable(struct tpiu_drvdata *drvdata)
+{
+	TPIU_UNLOCK(drvdata);
 
 	tpiu_writel(drvdata, 0x3000, TPIU_FFCR);
 	tpiu_writel(drvdata, 0x3040, TPIU_FFCR);
 
-	TPIU_LOCK();
+	TPIU_LOCK(drvdata);
 }
 
-void tpiu_disable(void)
+static void tpiu_disable(struct coresight_device *csdev)
 {
-	__tpiu_disable();
-	drvdata->enabled = false;
+	struct tpiu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+	__tpiu_disable(drvdata);
+
+	clk_disable_unprepare(drvdata->clk);
+
 	dev_info(drvdata->dev, "TPIU disabled\n");
 }
 
+static const struct coresight_ops_sink tpiu_sink_ops = {
+	.enable		= tpiu_enable,
+	.disable	= tpiu_disable,
+};
+
+static const struct coresight_ops tpiu_cs_ops = {
+	.sink_ops	= &tpiu_sink_ops,
+};
+
 static int __devinit tpiu_probe(struct platform_device *pdev)
 {
 	int ret;
+	struct tpiu_drvdata *drvdata;
 	struct resource *res;
+	struct coresight_desc *desc;
 
 	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;
+	platform_set_drvdata(pdev, drvdata);
 
 	drvdata->clk = clk_get(drvdata->dev, "core_clk");
 	if (IS_ERR(drvdata->clk)) {
@@ -123,12 +161,32 @@
 	ret = clk_prepare_enable(drvdata->clk);
 	if (ret)
 		goto err_clk_enable;
-	__tpiu_disable();
+	__tpiu_disable(drvdata);
 	clk_disable_unprepare(drvdata->clk);
 
+	desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+	if (!desc) {
+		ret = -ENOMEM;
+		goto err_kzalloc_desc;
+	}
+	desc->type = CORESIGHT_DEV_TYPE_SINK;
+	desc->subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_PORT;
+	desc->ops = &tpiu_cs_ops;
+	desc->pdata = pdev->dev.platform_data;
+	desc->dev = &pdev->dev;
+	desc->owner = THIS_MODULE;
+	drvdata->csdev = coresight_register(desc);
+	if (IS_ERR(drvdata->csdev)) {
+		ret = PTR_ERR(drvdata->csdev);
+		goto err_coresight_register;
+	}
+	kfree(desc);
+
 	dev_info(drvdata->dev, "TPIU initialized\n");
 	return 0;
-
+err_coresight_register:
+	kfree(desc);
+err_kzalloc_desc:
 err_clk_enable:
 err_clk_rate:
 	clk_put(drvdata->clk);
@@ -144,17 +202,17 @@
 
 static int __devexit tpiu_remove(struct platform_device *pdev)
 {
-	if (drvdata->enabled)
-		tpiu_disable();
+	struct tpiu_drvdata *drvdata = platform_get_drvdata(pdev);
+
+	coresight_unregister(drvdata->csdev);
 	clk_put(drvdata->clk);
 	iounmap(drvdata->base);
 	kfree(drvdata);
-
 	return 0;
 }
 
 static struct of_device_id tpiu_match[] = {
-	{.compatible = "qcom,msm-tpiu"},
+	{.compatible = "coresight-tpiu"},
 	{}
 };
 
@@ -162,7 +220,7 @@
 	.probe          = tpiu_probe,
 	.remove         = __devexit_p(tpiu_remove),
 	.driver         = {
-		.name   = "msm_tpiu",
+		.name   = "coresight-tpiu",
 		.owner	= THIS_MODULE,
 		.of_match_table = tpiu_match,
 	},
diff --git a/drivers/coresight/coresight.c b/drivers/coresight/coresight.c
index a17ac9a..0c6b56a 100644
--- a/drivers/coresight/coresight.c
+++ b/drivers/coresight/coresight.c
@@ -28,7 +28,6 @@
 
 
 #define NO_SINK		(-1)
-#define MAX_STR_LEN	(65535)
 
 
 static int curr_sink = NO_SINK;
@@ -343,7 +342,7 @@
 	up(&coresight_mutex);
 	return ret;
 }
-EXPORT_SYMBOL(coresight_enable);
+EXPORT_SYMBOL_GPL(coresight_enable);
 
 void coresight_disable(struct coresight_device *csdev)
 {
@@ -366,7 +365,7 @@
 out:
 	up(&coresight_mutex);
 }
-EXPORT_SYMBOL(coresight_disable);
+EXPORT_SYMBOL_GPL(coresight_disable);
 
 static ssize_t coresight_show_type(struct device *dev,
 				   struct device_attribute *attr, char *buf)
@@ -626,7 +625,7 @@
 err_kzalloc_csdev:
 	return ERR_PTR(ret);
 }
-EXPORT_SYMBOL(coresight_register);
+EXPORT_SYMBOL_GPL(coresight_register);
 
 void coresight_unregister(struct coresight_device *csdev)
 {
@@ -638,7 +637,7 @@
 		put_device(&csdev->dev);
 	}
 }
-EXPORT_SYMBOL(coresight_unregister);
+EXPORT_SYMBOL_GPL(coresight_unregister);
 
 static int __init coresight_init(void)
 {
@@ -653,300 +652,3 @@
 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/Makefile b/drivers/gpu/msm/Makefile
index 6cdb5f1..c7ed329 100644
--- a/drivers/gpu/msm/Makefile
+++ b/drivers/gpu/msm/Makefile
@@ -35,6 +35,7 @@
 
 msm_z180-y += \
 	z180.o \
+	z180_postmortem.o \
 	z180_trace.o
 
 msm_kgsl_core-objs = $(msm_kgsl_core-y)
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index f7d1e59..6a894c8 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -32,8 +32,6 @@
 
 #include "adreno.h"
 #include "adreno_pm4types.h"
-#include "adreno_debugfs.h"
-#include "adreno_postmortem.h"
 
 #include "a2xx_reg.h"
 #include "a3xx_reg.h"
@@ -1639,7 +1637,7 @@
 		 * Trigger an automatic dump of the state to
 		 * the console
 		 */
-		adreno_postmortem_dump(device, 0);
+		kgsl_postmortem_dump(device, 0);
 
 		/*
 		 * Make a GPU snapshot.  For now, do it after the PM dump so we
@@ -2452,6 +2450,7 @@
 	.drawctxt_create = adreno_drawctxt_create,
 	.drawctxt_destroy = adreno_drawctxt_destroy,
 	.setproperty = adreno_setproperty,
+	.postmortem_dump = adreno_dump,
 };
 
 static struct platform_driver adreno_platform_driver = {
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 279e7ed..b923049e 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -49,6 +49,8 @@
 #define ADRENO_DEFAULT_PWRSCALE_POLICY  NULL
 #endif
 
+void adreno_debugfs_init(struct kgsl_device *device);
+
 #define ADRENO_ISTORE_START 0x5000 /* Istore offset */
 
 #define ADRENO_NUM_CTX_SWITCH_ALLOWED_BEFORE_DRAW	50
@@ -166,6 +168,8 @@
 void adreno_regwrite(struct kgsl_device *device, unsigned int offsetwords,
 				unsigned int value);
 
+int adreno_dump(struct kgsl_device *device, int manual);
+
 struct kgsl_memdesc *adreno_find_region(struct kgsl_device *device,
 						unsigned int pt_base,
 						unsigned int gpuaddr,
diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c
index e3c9a18..bb3da40 100644
--- a/drivers/gpu/msm/adreno_debugfs.c
+++ b/drivers/gpu/msm/adreno_debugfs.c
@@ -18,67 +18,11 @@
 #include <linux/io.h>
 
 #include "kgsl.h"
-#include "adreno_postmortem.h"
 #include "adreno.h"
 
 #include "a2xx_reg.h"
 
 unsigned int kgsl_cff_dump_enable;
-int adreno_pm_regs_enabled;
-int adreno_pm_ib_enabled;
-
-static struct dentry *pm_d_debugfs;
-
-static int pm_dump_set(void *data, u64 val)
-{
-	struct kgsl_device *device = data;
-
-	if (val) {
-		mutex_lock(&device->mutex);
-		adreno_postmortem_dump(device, 1);
-		mutex_unlock(&device->mutex);
-	}
-
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(pm_dump_fops,
-			NULL,
-			pm_dump_set, "%llu\n");
-
-static int pm_regs_enabled_set(void *data, u64 val)
-{
-	adreno_pm_regs_enabled = val ? 1 : 0;
-	return 0;
-}
-
-static int pm_regs_enabled_get(void *data, u64 *val)
-{
-	*val = adreno_pm_regs_enabled;
-	return 0;
-}
-
-static int pm_ib_enabled_set(void *data, u64 val)
-{
-	adreno_pm_ib_enabled = val ? 1 : 0;
-	return 0;
-}
-
-static int pm_ib_enabled_get(void *data, u64 *val)
-{
-	*val = adreno_pm_ib_enabled;
-	return 0;
-}
-
-
-DEFINE_SIMPLE_ATTRIBUTE(pm_regs_enabled_fops,
-			pm_regs_enabled_get,
-			pm_regs_enabled_set, "%llu\n");
-
-DEFINE_SIMPLE_ATTRIBUTE(pm_ib_enabled_fops,
-			pm_ib_enabled_get,
-			pm_ib_enabled_set, "%llu\n");
-
 
 static int kgsl_cff_dump_enable_set(void *data, u64 val)
 {
@@ -116,23 +60,9 @@
 		&adreno_dev->wait_timeout);
 	debugfs_create_u32("ib_check", 0644, device->d_debugfs,
 			   &adreno_dev->ib_check_level);
-
 	/* By Default enable fast hang detection */
 	adreno_dev->fast_hang_detect = 1;
 	debugfs_create_u32("fast_hang_detect", 0644, device->d_debugfs,
 			   &adreno_dev->fast_hang_detect);
 
-	/* Create post mortem control files */
-
-	pm_d_debugfs = debugfs_create_dir("postmortem", device->d_debugfs);
-
-	if (IS_ERR(pm_d_debugfs))
-		return;
-
-	debugfs_create_file("dump",  0600, pm_d_debugfs, device,
-			    &pm_dump_fops);
-	debugfs_create_file("regs_enabled", 0644, pm_d_debugfs, device,
-			    &pm_regs_enabled_fops);
-	debugfs_create_file("ib_enabled", 0644, pm_d_debugfs, device,
-				    &pm_ib_enabled_fops);
 }
diff --git a/drivers/gpu/msm/adreno_debugfs.h b/drivers/gpu/msm/adreno_debugfs.h
deleted file mode 100644
index 5f8d89a..0000000
--- a/drivers/gpu/msm/adreno_debugfs.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Copyright (c) 2002,2008-2012, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-#ifndef __ADRENO_DEBUGFS_H
-#define __ADRENO_DEBUGFS_H
-
-#ifdef CONFIG_DEBUG_FS
-
-int adreno_debugfs_init(struct kgsl_device *device);
-
-extern int adreno_pm_regs_enabled;
-extern int adreno_pm_ib_enabled;
-
-static inline int is_adreno_pm_regs_enabled(void)
-{
-	return adreno_pm_regs_enabled;
-}
-
-static inline int is_adreno_pm_ib_enabled(void)
-{
-	return adreno_pm_ib_enabled;
-}
-
-#else
-static inline int adreno_debugfs_init(struct kgsl_device *device)
-{
-	return 0;
-}
-
-static inline int kgsl_pmregs_enabled(void)
-{
-	/* If debugfs is turned off, then always print registers */
-	return 1;
-}
-#endif
-
-#endif /* __ADRENO_DEBUGFS_H */
diff --git a/drivers/gpu/msm/adreno_postmortem.c b/drivers/gpu/msm/adreno_postmortem.c
index 3cc4bcf..2038c10 100644
--- a/drivers/gpu/msm/adreno_postmortem.c
+++ b/drivers/gpu/msm/adreno_postmortem.c
@@ -19,8 +19,6 @@
 #include "adreno.h"
 #include "adreno_pm4types.h"
 #include "adreno_ringbuffer.h"
-#include "adreno_postmortem.h"
-#include "adreno_debugfs.h"
 #include "kgsl_cffdump.h"
 #include "kgsl_pwrctrl.h"
 
@@ -678,7 +676,7 @@
 		"MH_INTERRUPT: MASK = %08X | STATUS   = %08X\n", r1, r2);
 }
 
-static int adreno_dump(struct kgsl_device *device)
+int adreno_dump(struct kgsl_device *device, int manual)
 {
 	unsigned int cp_ib1_base, cp_ib1_bufsz;
 	unsigned int cp_ib2_base, cp_ib2_bufsz;
@@ -834,7 +832,7 @@
 		cp_rb_base, cp_rb_rptr, cp_rb_wptr, read_idx);
 	adreno_dump_rb(device, rb_copy, num_item<<2, read_idx, rb_count);
 
-	if (is_adreno_pm_ib_enabled()) {
+	if (device->pm_ib_enabled) {
 		for (read_idx = NUM_DWORDS_OF_RINGBUFFER_HISTORY;
 			read_idx >= 0; --read_idx) {
 			uint32_t this_cmd = rb_copy[read_idx];
@@ -865,7 +863,7 @@
 	}
 
 	/* Dump the registers if the user asked for it */
-	if (is_adreno_pm_regs_enabled()) {
+	if (device->pm_regs_enabled) {
 		if (adreno_is_a20x(adreno_dev))
 			adreno_dump_regs(device, a200_registers,
 					a200_registers_count);
@@ -885,85 +883,3 @@
 end:
 	return result;
 }
-
-/**
- * adreno_postmortem_dump - Dump the current GPU state
- * @device - A pointer to the KGSL device to dump
- * @manual - A flag that indicates if this was a manually triggered
- *           dump (from debugfs).  If zero, then this is assumed to be a
- *           dump automaticlaly triggered from a hang
-*/
-
-int adreno_postmortem_dump(struct kgsl_device *device, int manual)
-{
-	bool saved_nap;
-	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
-
-	BUG_ON(device == NULL);
-
-	kgsl_cffdump_hang(device->id);
-
-	/* For a manual dump, make sure that the system is idle */
-
-	if (manual) {
-		if (device->active_cnt != 0) {
-			mutex_unlock(&device->mutex);
-			wait_for_completion(&device->suspend_gate);
-			mutex_lock(&device->mutex);
-		}
-
-		if (device->state == KGSL_STATE_ACTIVE)
-			kgsl_idle(device,  KGSL_TIMEOUT_DEFAULT);
-
-	}
-	KGSL_LOG_DUMP(device, "POWER: FLAGS = %08lX | ACTIVE POWERLEVEL = %08X",
-			pwr->power_flags, pwr->active_pwrlevel);
-
-	KGSL_LOG_DUMP(device, "POWER: INTERVAL TIMEOUT = %08X ",
-		pwr->interval_timeout);
-
-	KGSL_LOG_DUMP(device, "GRP_CLK = %lu ",
-				  kgsl_get_clkrate(pwr->grp_clks[0]));
-
-	KGSL_LOG_DUMP(device, "BUS CLK = %lu ",
-		kgsl_get_clkrate(pwr->ebi1_clk));
-
-	/* Disable the idle timer so we don't get interrupted */
-	del_timer_sync(&device->idle_timer);
-	mutex_unlock(&device->mutex);
-	flush_workqueue(device->work_queue);
-	mutex_lock(&device->mutex);
-
-	/* Turn off napping to make sure we have the clocks full
-	   attention through the following process */
-	saved_nap = device->pwrctrl.nap_allowed;
-	device->pwrctrl.nap_allowed = false;
-
-	/* Force on the clocks */
-	kgsl_pwrctrl_wake(device);
-
-	/* Disable the irq */
-	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
-
-	adreno_dump(device);
-
-	/* Restore nap mode */
-	device->pwrctrl.nap_allowed = saved_nap;
-
-	/* On a manual trigger, turn on the interrupts and put
-	   the clocks to sleep.  They will recover themselves
-	   on the next event.  For a hang, leave things as they
-	   are until recovery kicks in. */
-
-	if (manual) {
-		kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON);
-
-		/* try to go into a sleep mode until the next event */
-		kgsl_pwrctrl_request_state(device, KGSL_STATE_SLEEP);
-		kgsl_pwrctrl_sleep(device);
-	}
-
-	KGSL_DRV_ERR(device, "Dump Finished\n");
-
-	return 0;
-}
diff --git a/drivers/gpu/msm/adreno_postmortem.h b/drivers/gpu/msm/adreno_postmortem.h
deleted file mode 100644
index b677800..0000000
--- a/drivers/gpu/msm/adreno_postmortem.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * 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 __ADRENO_POSTMORTEM_H
-#define __ADRENO_POSTMORTEM_H
-
-struct kgsl_device;
-
-int adreno_postmortem_dump(struct kgsl_device *device, int manual);
-
-#endif /* __ADRENO_POSTMORTEM_H */
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index 49786ba..ca9e335 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -22,7 +22,6 @@
 #include "adreno.h"
 #include "adreno_pm4types.h"
 #include "adreno_ringbuffer.h"
-#include "adreno_debugfs.h"
 
 #include "a2xx_reg.h"
 #include "a3xx_reg.h"
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 62e1521..53eff77 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -2176,7 +2176,7 @@
 static long kgsl_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
 {
 	struct kgsl_device_private *dev_priv = filep->private_data;
-	unsigned int nr = _IOC_NR(cmd);
+	unsigned int nr;
 	kgsl_ioctl_func_t func;
 	int lock, ret;
 	char ustack[64];
@@ -2192,6 +2192,8 @@
 	else if (cmd == IOCTL_KGSL_CMDSTREAM_READTIMESTAMP_OLD)
 		cmd = IOCTL_KGSL_CMDSTREAM_READTIMESTAMP;
 
+	nr = _IOC_NR(cmd);
+
 	if (cmd & (IOC_IN | IOC_OUT)) {
 		if (_IOC_SIZE(cmd) < sizeof(ustack))
 			uptr = ustack;
@@ -2216,7 +2218,20 @@
 	}
 
 	if (nr < ARRAY_SIZE(kgsl_ioctl_funcs) &&
-	    kgsl_ioctl_funcs[nr].func != NULL) {
+		kgsl_ioctl_funcs[nr].func != NULL) {
+
+		/*
+		 * Make sure that nobody tried to send us a malformed ioctl code
+		 * with a valid NR but bogus flags
+		 */
+
+		if (kgsl_ioctl_funcs[nr].cmd != cmd) {
+			KGSL_DRV_ERR(dev_priv->device,
+				"Malformed ioctl code %08x\n", cmd);
+			ret = -ENOIOCTLCMD;
+			goto done;
+		}
+
 		func = kgsl_ioctl_funcs[nr].func;
 		lock = kgsl_ioctl_funcs[nr].lock;
 	} else {
@@ -2570,6 +2585,83 @@
 }
 EXPORT_SYMBOL(kgsl_device_platform_probe);
 
+int kgsl_postmortem_dump(struct kgsl_device *device, int manual)
+{
+	bool saved_nap;
+	struct kgsl_pwrctrl *pwr = &device->pwrctrl;
+
+	BUG_ON(device == NULL);
+
+	kgsl_cffdump_hang(device->id);
+
+	/* For a manual dump, make sure that the system is idle */
+
+	if (manual) {
+		if (device->active_cnt != 0) {
+			mutex_unlock(&device->mutex);
+			wait_for_completion(&device->suspend_gate);
+			mutex_lock(&device->mutex);
+		}
+
+		if (device->state == KGSL_STATE_ACTIVE)
+			kgsl_idle(device,  KGSL_TIMEOUT_DEFAULT);
+
+	}
+	KGSL_LOG_DUMP(device, "|%s| Dump Started\n", device->name);
+	KGSL_LOG_DUMP(device, "POWER: FLAGS = %08lX | ACTIVE POWERLEVEL = %08X",
+			pwr->power_flags, pwr->active_pwrlevel);
+
+	KGSL_LOG_DUMP(device, "POWER: INTERVAL TIMEOUT = %08X ",
+		pwr->interval_timeout);
+
+	KGSL_LOG_DUMP(device, "GRP_CLK = %lu ",
+				  kgsl_get_clkrate(pwr->grp_clks[0]));
+
+	KGSL_LOG_DUMP(device, "BUS CLK = %lu ",
+		kgsl_get_clkrate(pwr->ebi1_clk));
+
+	/* Disable the idle timer so we don't get interrupted */
+	del_timer_sync(&device->idle_timer);
+	mutex_unlock(&device->mutex);
+	flush_workqueue(device->work_queue);
+	mutex_lock(&device->mutex);
+
+	/* Turn off napping to make sure we have the clocks full
+	   attention through the following process */
+	saved_nap = device->pwrctrl.nap_allowed;
+	device->pwrctrl.nap_allowed = false;
+
+	/* Force on the clocks */
+	kgsl_pwrctrl_wake(device);
+
+	/* Disable the irq */
+	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
+
+	/*Call the device specific postmortem dump function*/
+	device->ftbl->postmortem_dump(device, manual);
+
+	/* Restore nap mode */
+	device->pwrctrl.nap_allowed = saved_nap;
+
+	/* On a manual trigger, turn on the interrupts and put
+	   the clocks to sleep.  They will recover themselves
+	   on the next event.  For a hang, leave things as they
+	   are until recovery kicks in. */
+
+	if (manual) {
+		kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON);
+
+		/* try to go into a sleep mode until the next event */
+		kgsl_pwrctrl_request_state(device, KGSL_STATE_SLEEP);
+		kgsl_pwrctrl_sleep(device);
+	}
+
+	KGSL_LOG_DUMP(device, "|%s| Dump Finished\n", device->name);
+
+	return 0;
+}
+EXPORT_SYMBOL(kgsl_postmortem_dump);
+
 void kgsl_device_platform_remove(struct kgsl_device *device)
 {
 	kgsl_device_snapshot_close(device);
diff --git a/drivers/gpu/msm/kgsl.h b/drivers/gpu/msm/kgsl.h
index 8a3345b..ac04c56 100644
--- a/drivers/gpu/msm/kgsl.h
+++ b/drivers/gpu/msm/kgsl.h
@@ -173,6 +173,7 @@
 #endif
 
 void kgsl_mem_entry_destroy(struct kref *kref);
+int kgsl_postmortem_dump(struct kgsl_device *device, int manual);
 
 struct kgsl_mem_entry *kgsl_get_mem_entry(unsigned int ptbase,
 		unsigned int gpuaddr, unsigned int size);
diff --git a/drivers/gpu/msm/kgsl_debugfs.c b/drivers/gpu/msm/kgsl_debugfs.c
index 328dd95..545d2b3 100644
--- a/drivers/gpu/msm/kgsl_debugfs.c
+++ b/drivers/gpu/msm/kgsl_debugfs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2008-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -22,6 +22,60 @@
 #define KGSL_LOG_LEVEL_MAX     7
 
 struct dentry *kgsl_debugfs_dir;
+static struct dentry *pm_d_debugfs;
+
+static int pm_dump_set(void *data, u64 val)
+{
+	struct kgsl_device *device = data;
+
+	if (val) {
+		mutex_lock(&device->mutex);
+		kgsl_postmortem_dump(device, 1);
+		mutex_unlock(&device->mutex);
+	}
+
+	return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(pm_dump_fops,
+			NULL,
+			pm_dump_set, "%llu\n");
+
+static int pm_regs_enabled_set(void *data, u64 val)
+{
+	struct kgsl_device *device = data;
+	device->pm_regs_enabled = val ? 1 : 0;
+	return 0;
+}
+
+static int pm_regs_enabled_get(void *data, u64 *val)
+{
+	struct kgsl_device *device = data;
+	*val = device->pm_regs_enabled;
+	return 0;
+}
+
+static int pm_ib_enabled_set(void *data, u64 val)
+{
+	struct kgsl_device *device = data;
+	device->pm_ib_enabled = val ? 1 : 0;
+	return 0;
+}
+
+static int pm_ib_enabled_get(void *data, u64 *val)
+{
+	struct kgsl_device *device = data;
+	*val = device->pm_ib_enabled;
+	return 0;
+}
+
+
+DEFINE_SIMPLE_ATTRIBUTE(pm_regs_enabled_fops,
+			pm_regs_enabled_get,
+			pm_regs_enabled_set, "%llu\n");
+
+DEFINE_SIMPLE_ATTRIBUTE(pm_ib_enabled_fops,
+			pm_ib_enabled_get,
+			pm_ib_enabled_set, "%llu\n");
 
 static inline int kgsl_log_set(unsigned int *log_val, void *data, u64 val)
 {
@@ -75,6 +129,21 @@
 				&mem_log_fops);
 	debugfs_create_file("log_level_pwr", 0644, device->d_debugfs, device,
 				&pwr_log_fops);
+
+	/* Create postmortem dump control files */
+
+	pm_d_debugfs = debugfs_create_dir("postmortem", device->d_debugfs);
+
+	if (IS_ERR(pm_d_debugfs))
+		return;
+
+	debugfs_create_file("dump",  0600, pm_d_debugfs, device,
+			    &pm_dump_fops);
+	debugfs_create_file("regs_enabled", 0644, pm_d_debugfs, device,
+			    &pm_regs_enabled_fops);
+	debugfs_create_file("ib_enabled", 0644, pm_d_debugfs, device,
+				    &pm_ib_enabled_fops);
+
 }
 
 void kgsl_core_debugfs_init(void)
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index 0336a20..d0932ef 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -110,6 +110,7 @@
 	int (*setproperty) (struct kgsl_device *device,
 		enum kgsl_property_type type, void *value,
 		unsigned int sizebytes);
+	int (*postmortem_dump) (struct kgsl_device *device, int manual);
 };
 
 /* MH register values */
@@ -196,6 +197,10 @@
 	struct work_struct ts_expired_ws;
 	struct list_head events;
 	s64 on_time;
+
+	/* Postmortem Control switches */
+	int pm_regs_enabled;
+	int pm_ib_enabled;
 };
 
 void kgsl_timestamp_expired(struct work_struct *work);
diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c
index c02274d..8e6c5c0 100644
--- a/drivers/gpu/msm/kgsl_mmu.c
+++ b/drivers/gpu/msm/kgsl_mmu.c
@@ -24,7 +24,6 @@
 #include "kgsl_mmu.h"
 #include "kgsl_device.h"
 #include "kgsl_sharedmem.h"
-#include "adreno_postmortem.h"
 
 #define KGSL_MMU_ALIGN_SHIFT    13
 #define KGSL_MMU_ALIGN_MASK     (~((1 << KGSL_MMU_ALIGN_SHIFT) - 1))
diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c
index 3504dfc..9037f3c 100644
--- a/drivers/gpu/msm/z180.c
+++ b/drivers/gpu/msm/z180.c
@@ -25,9 +25,6 @@
 #define DRIVER_VERSION_MAJOR   3
 #define DRIVER_VERSION_MINOR   1
 
-#define Z180_DEVICE(device) \
-		KGSL_CONTAINER_OF(device, struct z180_device, dev)
-
 #define GSL_VGC_INT_MASK \
 	 (REG_VGC_IRQSTATUS__MH_MASK | \
 	  REG_VGC_IRQSTATUS__G2D_MASK | \
@@ -41,16 +38,12 @@
 #define VGV3_CONTROL_MARKADD_FSHIFT 0
 #define VGV3_CONTROL_MARKADD_FMASK 0xfff
 
-#define Z180_PACKET_SIZE 15
 #define Z180_MARKER_SIZE 10
 #define Z180_CALL_CMD     0x1000
 #define Z180_MARKER_CMD   0x8000
 #define Z180_STREAM_END_CMD 0x9000
 #define Z180_STREAM_PACKET 0x7C000176
 #define Z180_STREAM_PACKET_CALL 0x7C000275
-#define Z180_PACKET_COUNT 8
-#define Z180_RB_SIZE (Z180_PACKET_SIZE*Z180_PACKET_COUNT \
-			  *sizeof(uint32_t))
 
 #define NUMTEXUNITS             4
 #define TEXUNITREGCOUNT         25
@@ -846,6 +839,7 @@
 	else if (timeout == 0) {
 		status = -ETIMEDOUT;
 		kgsl_pwrctrl_set_state(device, KGSL_STATE_HUNG);
+		kgsl_postmortem_dump(device, 0);
 	} else
 		status = timeout;
 
@@ -936,6 +930,7 @@
 	.drawctxt_create = NULL,
 	.drawctxt_destroy = z180_drawctxt_destroy,
 	.ioctl = NULL,
+	.postmortem_dump = z180_dump,
 };
 
 static struct platform_device_id z180_id_table[] = {
diff --git a/drivers/gpu/msm/z180.h b/drivers/gpu/msm/z180.h
index e5c5ef3..6e81a9d 100644
--- a/drivers/gpu/msm/z180.h
+++ b/drivers/gpu/msm/z180.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -19,6 +19,13 @@
 #define DEVICE_2D0_NAME "kgsl-2d0"
 #define DEVICE_2D1_NAME "kgsl-2d1"
 
+#define Z180_PACKET_SIZE 15
+#define Z180_PACKET_COUNT 8
+#define Z180_RB_SIZE (Z180_PACKET_SIZE*Z180_PACKET_COUNT \
+			  *sizeof(uint32_t))
+#define Z180_DEVICE(device) \
+		KGSL_CONTAINER_OF(device, struct z180_device, dev)
+
 #define Z180_DEFAULT_PWRSCALE_POLICY  NULL
 
 struct z180_ringbuffer {
@@ -34,4 +41,6 @@
 	spinlock_t cmdwin_lock;
 };
 
+int z180_dump(struct kgsl_device *, int);
+
 #endif /* __Z180_H */
diff --git a/drivers/gpu/msm/z180_postmortem.c b/drivers/gpu/msm/z180_postmortem.c
new file mode 100644
index 0000000..a9b0c50
--- /dev/null
+++ b/drivers/gpu/msm/z180_postmortem.c
@@ -0,0 +1,229 @@
+/* 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 "kgsl.h"
+#include "kgsl_device.h"
+#include "z180.h"
+#include "z180_reg.h"
+
+#define Z180_STREAM_PACKET_CALL 0x7C000275
+
+/* Postmortem Dump formatted Output parameters */
+
+/* Number of Words per dump data line */
+#define WORDS_PER_LINE 8
+
+/* Number of spaces per dump data line */
+#define NUM_SPACES (WORDS_PER_LINE - 1)
+
+/*
+ * Output dump data is formatted as string, hence number of chars
+ * per line for line string allocation
+ */
+#define CHARS_PER_LINE  \
+	((WORDS_PER_LINE * (2*sizeof(unsigned int))) + NUM_SPACES + 1)
+
+/* Z180 registers (byte offsets) to be dumped */
+static const unsigned int regs_to_dump[] = {
+		ADDR_VGC_VERSION,
+		ADDR_VGC_SYSSTATUS,
+		ADDR_VGC_IRQSTATUS,
+		ADDR_VGC_IRQENABLE,
+		ADDR_VGC_IRQ_ACTIVE_CNT,
+		ADDR_VGC_CLOCKEN,
+		ADDR_VGC_MH_DATA_ADDR,
+		ADDR_VGC_GPR0,
+		ADDR_VGC_GPR1,
+		ADDR_VGC_BUSYCNT,
+		ADDR_VGC_FIFOFREE,
+};
+
+/**
+ * z180_dump_regs - Dumps all of Z180 external registers. Prints the word offset
+ * of the register in each output line.
+ * @device: kgsl_device pointer to the Z180 core
+ */
+static void z180_dump_regs(struct kgsl_device *device)
+{
+	unsigned int i;
+	unsigned int reg_val;
+
+	KGSL_LOG_DUMP(device, "Z180 Register Dump\n");
+	for (i = 0; i < ARRAY_SIZE(regs_to_dump); i++) {
+		kgsl_regread(device,
+				regs_to_dump[i]/sizeof(unsigned int), &reg_val);
+		KGSL_LOG_DUMP(device, "REG: %04X: %08X\n",
+				regs_to_dump[i]/sizeof(unsigned int), reg_val);
+	}
+}
+
+/**
+ * z180_dump_ringbuffer - Dumps the Z180 core's ringbuffer contents
+ * @device: kgsl_device pointer to the z180 core
+ */
+static void z180_dump_ringbuffer(struct kgsl_device *device)
+{
+	unsigned int rb_size;
+	unsigned int *rb_hostptr;
+	unsigned int rb_words;
+	unsigned int rb_gpuaddr;
+	struct z180_device *z180_dev = Z180_DEVICE(device);
+	unsigned int i;
+	char linebuf[CHARS_PER_LINE];
+
+	KGSL_LOG_DUMP(device, "Z180 ringbuffer dump\n");
+
+	rb_hostptr = (unsigned int *) z180_dev->ringbuffer.cmdbufdesc.hostptr;
+
+	rb_size = Z180_RB_SIZE;
+	rb_gpuaddr = z180_dev->ringbuffer.cmdbufdesc.gpuaddr;
+
+	rb_words = rb_size/sizeof(unsigned int);
+
+	KGSL_LOG_DUMP(device, "ringbuffer size: %u\n", rb_size);
+
+	KGSL_LOG_DUMP(device, "rb_words: %d\n", rb_words);
+
+	for (i = 0; i < rb_words; i += WORDS_PER_LINE) {
+		hex_dump_to_buffer(rb_hostptr+i,
+				rb_size - i*sizeof(unsigned int),
+				WORDS_PER_LINE*sizeof(unsigned int),
+				sizeof(unsigned int), linebuf,
+				sizeof(linebuf), false);
+		KGSL_LOG_DUMP(device, "RB: %04X: %s\n",
+				rb_gpuaddr + i*sizeof(unsigned int), linebuf);
+	}
+}
+
+
+static void z180_dump_ib(struct kgsl_device *device)
+{
+	unsigned int rb_size;
+	unsigned int *rb_hostptr;
+	unsigned int rb_words;
+	unsigned int rb_gpuaddr;
+	unsigned int ib_gpuptr = 0;
+	unsigned int ib_size = 0;
+	void *ib_hostptr = NULL;
+	int rb_slot_num = -1;
+	struct z180_device *z180_dev = Z180_DEVICE(device);
+	struct kgsl_mem_entry *entry = NULL;
+	unsigned int pt_base;
+	unsigned int i;
+	unsigned int j;
+	char linebuf[CHARS_PER_LINE];
+	unsigned int current_ib_slot;
+	unsigned int len;
+	unsigned int rowsize;
+	KGSL_LOG_DUMP(device, "Z180 IB dump\n");
+
+	rb_hostptr = (unsigned int *) z180_dev->ringbuffer.cmdbufdesc.hostptr;
+
+	rb_size = Z180_RB_SIZE;
+	rb_gpuaddr = z180_dev->ringbuffer.cmdbufdesc.gpuaddr;
+
+	rb_words = rb_size/sizeof(unsigned int);
+
+	KGSL_LOG_DUMP(device, "Ringbuffer size (bytes): %u\n", rb_size);
+
+	KGSL_LOG_DUMP(device, "rb_words: %d\n", rb_words);
+
+	pt_base = kgsl_mmu_get_current_ptbase(&device->mmu);
+
+	/* Dump the current IB */
+	for (i = 0; i < rb_words; i++) {
+		if (rb_hostptr[i] == Z180_STREAM_PACKET_CALL) {
+
+			rb_slot_num++;
+			current_ib_slot =
+				z180_dev->current_timestamp % Z180_PACKET_COUNT;
+			if (rb_slot_num != current_ib_slot)
+				continue;
+
+			ib_gpuptr = rb_hostptr[i+1];
+
+			entry = kgsl_get_mem_entry(pt_base, ib_gpuptr, 1);
+
+			if (entry == NULL) {
+				KGSL_LOG_DUMP(device,
+				"IB mem entry not found for ringbuffer slot#: %d\n",
+				rb_slot_num);
+				continue;
+			}
+
+			ib_hostptr = kgsl_memdesc_map(&entry->memdesc);
+
+			if (ib_hostptr == NULL) {
+				KGSL_LOG_DUMP(device,
+				"Could not map IB to kernel memory, Ringbuffer Slot: %d\n",
+				rb_slot_num);
+				continue;
+			}
+
+			ib_size = entry->memdesc.size;
+			KGSL_LOG_DUMP(device,
+				"IB size: %dbytes, IB size in words: %d\n",
+				ib_size,
+				ib_size/sizeof(unsigned int));
+
+			for (j = 0; j < ib_size; j += WORDS_PER_LINE) {
+				len = ib_size - j*sizeof(unsigned int);
+				rowsize = WORDS_PER_LINE*sizeof(unsigned int);
+				hex_dump_to_buffer(ib_hostptr+j, len, rowsize,
+						sizeof(unsigned int), linebuf,
+						sizeof(linebuf), false);
+				KGSL_LOG_DUMP(device, "IB%d: %04X: %s\n",
+						rb_slot_num,
+						(rb_gpuaddr +
+						j*sizeof(unsigned int)),
+						linebuf);
+			}
+			KGSL_LOG_DUMP(device, "IB Dump Finished\n");
+		}
+	}
+}
+
+
+/**
+ * z180_dump - Dumps the Z180 ringbuffer and registers (and IBs if asked for)
+ * for postmortem
+ * analysis.
+ * @device: kgsl_device pointer to the Z180 core
+ */
+int z180_dump(struct kgsl_device *device, int manual)
+{
+	struct z180_device *z180_dev = Z180_DEVICE(device);
+
+	mb();
+
+	KGSL_LOG_DUMP(device, "Retired Timestamp: %d\n", z180_dev->timestamp);
+	KGSL_LOG_DUMP(device,
+			"Current Timestamp: %d\n", z180_dev->current_timestamp);
+
+	/* Dump ringbuffer */
+	z180_dump_ringbuffer(device);
+
+	/* Dump registers */
+	z180_dump_regs(device);
+
+	/* Dump IBs, if asked for */
+	if (device->pm_ib_enabled)
+		z180_dump_ib(device);
+
+	/* Get the stack trace if the dump was automatic */
+	if (!manual)
+		BUG_ON(1);
+
+	return 0;
+}
+
diff --git a/drivers/gpu/msm/z180_reg.h b/drivers/gpu/msm/z180_reg.h
index 5b6c001..07d60b9 100644
--- a/drivers/gpu/msm/z180_reg.h
+++ b/drivers/gpu/msm/z180_reg.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -45,5 +45,12 @@
 #define ADDR_VGV3_NEXTADDR               0x0075
 #define ADDR_VGV3_NEXTCMD                0x0076
 #define ADDR_VGV3_WRITEADDR              0x0072
+#define ADDR_VGC_VERSION				 0x400
+#define ADDR_VGC_SYSSTATUS				 0x410
+#define ADDR_VGC_CLOCKEN				 0x508
+#define ADDR_VGC_GPR0					 0x520
+#define ADDR_VGC_GPR1					 0x528
+#define ADDR_VGC_BUSYCNT				 0x530
+#define ADDR_VGC_FIFOFREE				 0x7c0
 
 #endif /* __Z180_REG_H */
diff --git a/drivers/media/video/msm_vidc/msm_vdec.c b/drivers/media/video/msm_vidc/msm_vdec.c
index a683315..c87211a 100644
--- a/drivers/media/video/msm_vidc/msm_vdec.c
+++ b/drivers/media/video/msm_vidc/msm_vdec.c
@@ -440,15 +440,16 @@
 	if (fmt) {
 		f->fmt.pix_mp.pixelformat = fmt->fourcc;
 		if (inst->in_reconfig == true) {
-			inst->height = inst->reconfig_height;
-			inst->width = inst->reconfig_width;
+			inst->prop.height = inst->reconfig_height;
+			inst->prop.width = inst->reconfig_width;
 		}
-		f->fmt.pix_mp.height = inst->height;
-		f->fmt.pix_mp.width = inst->width;
+		f->fmt.pix_mp.height = inst->prop.height;
+		f->fmt.pix_mp.width = inst->prop.width;
 		f->fmt.pix_mp.num_planes = fmt->num_planes;
 		for (i = 0; i < fmt->num_planes; ++i) {
 			f->fmt.pix_mp.plane_fmt[i].sizeimage =
-			fmt->get_frame_size(i, inst->height, inst->width);
+			fmt->get_frame_size(i, inst->prop.height,
+				inst->prop.width);
 		}
 	} else {
 		pr_err("Buf type not recognized, type = %d\n",
@@ -584,7 +585,7 @@
 			*num_buffers = MIN_NUM_OUTPUT_BUFFERS;
 		for (i = 0; i < *num_planes; i++) {
 			sizes[i] = inst->fmts[OUTPUT_PORT]->get_frame_size(
-					i, inst->height, inst->width);
+					i, inst->prop.height, inst->prop.width);
 		}
 		break;
 	case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
diff --git a/drivers/media/video/msm_vidc/msm_venc.c b/drivers/media/video/msm_vidc/msm_venc.c
index f030163..14baf79 100644
--- a/drivers/media/video/msm_vidc/msm_venc.c
+++ b/drivers/media/video/msm_vidc/msm_venc.c
@@ -1201,7 +1201,7 @@
 	inst->fmts[OUTPUT_PORT] = &venc_formats[0];
 	inst->prop.height = DEFAULT_HEIGHT;
 	inst->prop.width = DEFAULT_WIDTH;
-	inst->prop.height = 30;
+	inst->prop.fps = 30;
 	return rc;
 }
 
diff --git a/drivers/media/video/msm_vidc/msm_vidc_common.c b/drivers/media/video/msm_vidc/msm_vidc_common.c
index 6835467..58dee31 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_common.c
+++ b/drivers/media/video/msm_vidc/msm_vidc_common.c
@@ -1126,7 +1126,7 @@
 		pr_err("inst: %p is already in state: %d\n", inst, inst->state);
 		goto exit;
 	}
-	ocmem_sz = get_ocmem_requirement(inst->height, inst->width);
+	ocmem_sz = get_ocmem_requirement(inst->prop.height, inst->prop.width);
 	rc = msm_comm_alloc_ocmem(inst->core, ocmem_sz);
 	if (rc)
 		pr_warn("Failed to allocate OCMEM. Performance will be impacted\n");
diff --git a/drivers/media/video/msm_vidc/msm_vidc_internal.h b/drivers/media/video/msm_vidc/msm_vidc_internal.h
index 992f39c..8c11de8 100644
--- a/drivers/media/video/msm_vidc/msm_vidc_internal.h
+++ b/drivers/media/video/msm_vidc/msm_vidc_internal.h
@@ -201,8 +201,6 @@
 	int session_type;
 	void *session;
 	struct session_prop prop;
-	u32 width;
-	u32 height;
 	int state;
 	const struct msm_vidc_format *fmts[MAX_PORT_NUM];
 	struct vb2_queue vb2_bufq[MAX_PORT_NUM];
diff --git a/drivers/media/video/vcap_vp.c b/drivers/media/video/vcap_vp.c
index f1f1c69..9f2ead4 100644
--- a/drivers/media/video/vcap_vp.c
+++ b/drivers/media/video/vcap_vp.c
@@ -273,10 +273,10 @@
 
 #ifdef TOP_FIELD_FIX
 	writel_iowmb(0x00000000 | vp_act->top_field << 0, VCAP_VP_CTRL);
-	writel_iowmb(0x00030000 | vp_act->top_field << 0, VCAP_VP_CTRL);
+	writel_iowmb(0x00010000 | vp_act->top_field << 0, VCAP_VP_CTRL);
 #else
 	writel_iowmb(0x00000000 | top_field, VCAP_VP_CTRL);
-	writel_iowmb(0x00030000 | top_field, VCAP_VP_CTRL);
+	writel_iowmb(0x00010000 | top_field, VCAP_VP_CTRL);
 #endif
 	enable_irq(dev->vpirq->start);
 	writel_iowmb(irq, VCAP_VP_INT_CLEAR);
@@ -420,58 +420,84 @@
 
 int init_motion_buf(struct vcap_client_data *c_data)
 {
+	int rc;
 	struct vcap_dev *dev = c_data->dev;
-	void *buf;
-	unsigned long motion_base_addr;
-	uint32_t size = ((c_data->vp_out_fmt.width + 63) >> 6) *
+	struct ion_handle *handle = NULL;
+	unsigned long paddr, ionflag = 0;
+	void *vaddr;
+	size_t len;
+	size_t size = ((c_data->vp_out_fmt.width + 63) >> 6) *
 		((c_data->vp_out_fmt.height + 7) >> 3) * 16;
 
-	if (c_data->vid_vp_action.bufMotion) {
+	if (c_data->vid_vp_action.motionHandle) {
 		pr_err("Motion buffer has already been created");
 		return -ENOEXEC;
 	}
 
-	buf = kzalloc(size, GFP_KERNEL);
-	if (!buf)
+	handle = ion_alloc(dev->ion_client, size, SZ_4K,
+			ION_HEAP(ION_CP_MM_HEAP_ID));
+	if (IS_ERR_OR_NULL(handle)) {
+		pr_err("%s: ion_alloc failed\n", __func__);
 		return -ENOMEM;
+	}
+	rc = ion_phys(dev->ion_client, handle, &paddr, &len);
+	if (rc < 0) {
+		pr_err("%s: ion_phys failed\n", __func__);
+		ion_free(dev->ion_client, handle);
+		return rc;
+	}
 
-	c_data->vid_vp_action.bufMotion = buf;
-	motion_base_addr = virt_to_phys(buf);
-	writel_iowmb(motion_base_addr, VCAP_VP_MOTION_EST_ADDR);
+	rc = ion_handle_get_flags(dev->ion_client, handle, &ionflag);
+	if (rc) {
+		pr_err("%s: get flags ion handle failed\n", __func__);
+		ion_free(dev->ion_client, handle);
+		return rc;
+	}
+
+	vaddr = ion_map_kernel(dev->ion_client, handle, ionflag);
+	if (IS_ERR(vaddr)) {
+		pr_err("%s: Map motion buffer failed\n", __func__);
+		ion_free(dev->ion_client, handle);
+		rc = -ENOMEM;
+		return rc;
+	}
+
+	memset(vaddr, 0, size);
+	c_data->vid_vp_action.motionHandle = handle;
+
+	vaddr = NULL;
+	ion_unmap_kernel(dev->ion_client, handle);
+
+	writel_iowmb(paddr, VCAP_VP_MOTION_EST_ADDR);
 	return 0;
 }
 
 void deinit_motion_buf(struct vcap_client_data *c_data)
 {
 	struct vcap_dev *dev = c_data->dev;
-	void *buf;
-
-	if (!c_data->vid_vp_action.bufMotion) {
+	if (!c_data->vid_vp_action.motionHandle) {
 		pr_err("Motion buffer has not been created");
 		return;
 	}
 
-	buf = c_data->vid_vp_action.bufMotion;
-
 	writel_iowmb(0x00000000, VCAP_VP_MOTION_EST_ADDR);
-	c_data->vid_vp_action.bufMotion = NULL;
-	kfree(buf);
+	ion_free(dev->ion_client, c_data->vid_vp_action.motionHandle);
+	c_data->vid_vp_action.motionHandle = NULL;
 	return;
 }
 
 int init_nr_buf(struct vcap_client_data *c_data)
 {
 	struct vcap_dev *dev = c_data->dev;
-	struct nr_buffer *buf;
-	uint32_t frame_size, tot_size, rc;
+	struct ion_handle *handle = NULL;
+	size_t frame_size, tot_size, len;
+	unsigned long paddr;
+	int rc;
 
-	if (c_data->vid_vp_action.bufNR.vaddr) {
+	if (c_data->vid_vp_action.bufNR.nr_handle) {
 		pr_err("NR buffer has already been created");
 		return -ENOEXEC;
 	}
-	buf = &c_data->vid_vp_action.bufNR;
-	if (!buf)
-		return -ENOMEM;
 
 	frame_size = c_data->vp_in_fmt.width * c_data->vp_in_fmt.height;
 	if (c_data->vp_in_fmt.pixfmt == V4L2_PIX_FMT_NV16)
@@ -479,19 +505,30 @@
 	else
 		tot_size = frame_size / 2 * 3;
 
-	buf->vaddr = kzalloc(tot_size, GFP_KERNEL);
-	if (!buf->vaddr)
+	handle = ion_alloc(dev->ion_client, tot_size, SZ_4K,
+			ION_HEAP(ION_CP_MM_HEAP_ID));
+	if (IS_ERR_OR_NULL(handle)) {
+		pr_err("%s: ion_alloc failed\n", __func__);
 		return -ENOMEM;
+	}
 
+	rc = ion_phys(dev->ion_client, handle, &paddr, &len);
+	if (rc < 0) {
+		pr_err("%s: ion_phys failed\n", __func__);
+		ion_free(dev->ion_client, handle);
+		return rc;
+	}
+
+	c_data->vid_vp_action.bufNR.nr_handle = handle;
 	update_nr_value(c_data);
 
-	buf->paddr = virt_to_phys(buf->vaddr);
+	c_data->vid_vp_action.bufNR.paddr = paddr;
 	rc = readl_relaxed(VCAP_VP_NR_CONFIG2);
-	rc |= 0x02D00001;
+	rc |= (((c_data->vp_out_fmt.width / 16) << 20) | 0x1);
 	writel_relaxed(rc, VCAP_VP_NR_CONFIG2);
-	writel_relaxed(buf->paddr, VCAP_VP_NR_T2_Y_BASE_ADDR);
-	writel_relaxed(buf->paddr + frame_size, VCAP_VP_NR_T2_C_BASE_ADDR);
-	buf->nr_pos = NRT2_BUF;
+	writel_relaxed(paddr, VCAP_VP_NR_T2_Y_BASE_ADDR);
+	writel_relaxed(paddr + frame_size, VCAP_VP_NR_T2_C_BASE_ADDR);
+	c_data->vid_vp_action.bufNR.nr_pos = NRT2_BUF;
 	return 0;
 }
 
@@ -501,20 +538,19 @@
 	struct nr_buffer *buf;
 	uint32_t rc;
 
-	if (!c_data->vid_vp_action.bufNR.vaddr) {
+	if (!c_data->vid_vp_action.bufNR.nr_handle) {
 		pr_err("NR buffer has not been created");
 		return;
 	}
-
 	buf = &c_data->vid_vp_action.bufNR;
 
 	rc = readl_relaxed(VCAP_VP_NR_CONFIG2);
-	rc &= !(0x02D00001);
+	rc &= !(0x0FF00001);
 	writel_relaxed(rc, VCAP_VP_NR_CONFIG2);
 
-	kfree(buf->vaddr);
+	ion_free(dev->ion_client, buf->nr_handle);
+	buf->nr_handle = NULL;
 	buf->paddr = 0;
-	buf->vaddr = NULL;
 	return;
 }
 
@@ -592,18 +628,26 @@
 {
 	struct vcap_dev *dev = c_data->dev;
 	unsigned int width, height;
+	struct ion_handle *handle = NULL;
 	unsigned long paddr;
-	void *temp;
+	size_t len;
 	uint32_t reg;
 	int rc = 0;
 
 	dprintk(2, "%s: Start VP dummy event\n", __func__);
-	temp = kzalloc(0x1200, GFP_KERNEL);
-	if (!temp) {
-		pr_err("%s: Failed to alloc mem", __func__);
+	handle = ion_alloc(dev->ion_client, 0x1200, SZ_4K,
+			ION_HEAP(ION_CP_MM_HEAP_ID));
+	if (IS_ERR_OR_NULL(handle)) {
+		pr_err("%s: ion_alloc failed\n", __func__);
 		return -ENOMEM;
 	}
-	paddr = virt_to_phys(temp);
+
+	rc = ion_phys(dev->ion_client, handle, &paddr, &len);
+	if (rc < 0) {
+		pr_err("%s: ion_phys failed\n", __func__);
+		ion_free(dev->ion_client, handle);
+		return rc;
+	}
 
 	width = c_data->vp_out_fmt.width;
 	height = c_data->vp_out_fmt.height;
@@ -626,7 +670,7 @@
 
 	writel_relaxed(0x01100101, VCAP_VP_INTERRUPT_ENABLE);
 	writel_iowmb(0x00000000, VCAP_VP_CTRL);
-	writel_iowmb(0x00030000, VCAP_VP_CTRL);
+	writel_iowmb(0x00010000, VCAP_VP_CTRL);
 
 	enable_irq(dev->vpirq->start);
 	rc = wait_event_interruptible_timeout(dev->vp_dummy_waitq,
@@ -650,7 +694,7 @@
 
 	c_data->vp_out_fmt.width = width;
 	c_data->vp_out_fmt.height = height;
-	kfree(temp);
+	ion_free(dev->ion_client, handle);
 
 	dprintk(2, "%s: Exit VP dummy event\n", __func__);
 	return rc;
@@ -748,10 +792,10 @@
 	writel_relaxed(0x01100101, VCAP_VP_INTERRUPT_ENABLE);
 #ifdef TOP_FIELD_FIX
 	writel_iowmb(0x00000000 | vp_act->top_field << 0, VCAP_VP_CTRL);
-	writel_iowmb(0x00030000 | vp_act->top_field << 0, VCAP_VP_CTRL);
+	writel_iowmb(0x00010000 | vp_act->top_field << 0, VCAP_VP_CTRL);
 #else
 	writel_iowmb(0x00000000 | top_field, VCAP_VP_CTRL);
-	writel_iowmb(0x00030000 | top_field, VCAP_VP_CTRL);
+	writel_iowmb(0x00010000 | top_field, VCAP_VP_CTRL);
 #endif
 	atomic_set(&c_data->dev->vp_enabled, 1);
 	enable_irq(dev->vpirq->start);
@@ -795,10 +839,10 @@
 	writel_relaxed(0x01100101, VCAP_VP_INTERRUPT_ENABLE);
 #ifdef TOP_FIELD_FIX
 	writel_iowmb(0x00000000 | vp_act->top_field << 0, VCAP_VP_CTRL);
-	writel_iowmb(0x00030000 | vp_act->top_field << 0, VCAP_VP_CTRL);
+	writel_iowmb(0x00010000 | vp_act->top_field << 0, VCAP_VP_CTRL);
 #else
 	writel_iowmb(0x00000000 | top_field, VCAP_VP_CTRL);
-	writel_iowmb(0x00030000 | top_field, VCAP_VP_CTRL);
+	writel_iowmb(0x00010000 | top_field, VCAP_VP_CTRL);
 #endif
 
 	atomic_set(&c_data->dev->vp_enabled, 1);
diff --git a/drivers/mfd/wcd9xxx-slimslave.c b/drivers/mfd/wcd9xxx-slimslave.c
index 5f839a8..71c68ac 100644
--- a/drivers/mfd/wcd9xxx-slimslave.c
+++ b/drivers/mfd/wcd9xxx-slimslave.c
@@ -555,18 +555,18 @@
 			 __func__, i, ch_num[i], idx, i, sph[i], grph);
 	}
 
-	/* slim_disconnect_port */
-	ret = slim_disconnect_ports(wcd9xxx->slim, sph, ch_cnt);
-	if (ret < 0) {
-		pr_err("%s: slim_disconnect_ports failed ret[%d]\n",
-		       __func__, ret);
-	}
 	/* slim_control_ch (REMOVE) */
 	ret = slim_control_ch(wcd9xxx->slim, grph, SLIM_CH_REMOVE, true);
 	if (ret < 0) {
 		pr_err("%s: slim_control_ch failed ret[%d]\n", __func__, ret);
 		goto err;
 	}
+	/* slim_disconnect_port */
+	ret = slim_disconnect_ports(wcd9xxx->slim, sph, ch_cnt);
+	if (ret < 0) {
+		pr_err("%s: slim_disconnect_ports failed ret[%d]\n",
+			 __func__, ret);
+	}
 	for (i = 0; i < ch_cnt; i++) {
 		idx = (ch_num[i] - BASE_CH_NUM - sh_ch.rx_port_start_offset);
 		rx[idx].grph = 0;
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 0e1267b..7a1760f 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -847,9 +847,13 @@
 
 	/* Ensure that above operation is completed before turning off clocks */
 	mb();
-	if (!motg->pdata->core_clk_always_on_workaround) {
+	/* Consider clocks on workaround flag only in case of bus suspend */
+	if (!(phy->state == OTG_STATE_B_PERIPHERAL &&
+		test_bit(A_BUS_SUSPEND, &motg->inputs)) ||
+	    !motg->pdata->core_clk_always_on_workaround) {
 		clk_disable_unprepare(motg->pclk);
 		clk_disable_unprepare(motg->core_clk);
+		motg->lpm_flags |= CLOCKS_DOWN;
 	}
 
 	/* usb phy no more require TCXO clock, hence vote for TCXO disable */
@@ -917,9 +921,10 @@
 		motg->lpm_flags &= ~XO_SHUTDOWN;
 	}
 
-	if (!motg->pdata->core_clk_always_on_workaround) {
+	if (motg->lpm_flags & CLOCKS_DOWN) {
 		clk_prepare_enable(motg->core_clk);
 		clk_prepare_enable(motg->pclk);
+		motg->lpm_flags &= ~CLOCKS_DOWN;
 	}
 
 	if (motg->lpm_flags & PHY_PWR_COLLAPSED) {
@@ -2726,10 +2731,14 @@
 		pr_debug("OTG IRQ: in LPM\n");
 		disable_irq_nosync(irq);
 		motg->async_int = 1;
-		if (atomic_read(&motg->pm_suspended))
+		if (atomic_read(&motg->pm_suspended)) {
 			motg->sm_work_pending = true;
-		else
+			if ((otg->phy->state == OTG_STATE_A_SUSPEND) ||
+				(otg->phy->state == OTG_STATE_A_WAIT_BCON))
+				set_bit(A_BUS_REQ, &motg->inputs);
+		} else {
 			pm_request_resume(otg->phy->dev);
+		}
 		return IRQ_HANDLED;
 	}
 
diff --git a/drivers/video/msm/external_common.c b/drivers/video/msm/external_common.c
index 46ef7b4..0976fc6 100644
--- a/drivers/video/msm/external_common.c
+++ b/drivers/video/msm/external_common.c
@@ -1452,21 +1452,21 @@
 	len += ret;
 
 	if (len && (format & TOP_AND_BOTTOM))
-		ret = snprintf(buf + len, PAGE_SIZE, ":%s",
+		ret = snprintf(buf + len, PAGE_SIZE - len, ":%s",
 			single_video_3d_format_2string(
 				format & TOP_AND_BOTTOM));
 	else
-		ret = snprintf(buf + len, PAGE_SIZE, "%s",
+		ret = snprintf(buf + len, PAGE_SIZE - len, "%s",
 			single_video_3d_format_2string(
 				format & TOP_AND_BOTTOM));
 	len += ret;
 
 	if (len && (format & SIDE_BY_SIDE_HALF))
-		ret = snprintf(buf + len, PAGE_SIZE, ":%s",
+		ret = snprintf(buf + len, PAGE_SIZE - len, ":%s",
 			single_video_3d_format_2string(
 				format & SIDE_BY_SIDE_HALF));
 	else
-		ret = snprintf(buf + len, PAGE_SIZE, "%s",
+		ret = snprintf(buf + len, PAGE_SIZE - len, "%s",
 			single_video_3d_format_2string(
 				format & SIDE_BY_SIDE_HALF));
 	len += ret;
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index ee73eea..9614a2d 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -2398,8 +2398,7 @@
 		if (!(mdp_pdata->cont_splash_enabled))
 			mdp4_hw_init();
 #else
-		if (!(mdp_pdata->cont_splash_enabled))
-			mdp_hw_init();
+		mdp_hw_init();
 #endif
 
 #ifdef CONFIG_FB_MSM_OVERLAY
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index ee4cb4e..b3f0b81 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -154,7 +154,6 @@
 		pr_err("%s: Error, mixer=%d iommu fndx=%d\n",
 				__func__, mixer, flist->fndx);
 		mdp4_stat.iommu_drop++;
-		mutex_unlock(&iommu_mutex);
 		return;
 	}
 
@@ -1663,6 +1662,12 @@
 
 	bspipe = ctrl->stage[mixer][MDP4_MIXER_STAGE_BASE];
 
+	/*
+	 * bspipe is clone here
+	 * get real pipe
+	 */
+	bspipe = mdp4_overlay_ndx2pipe(bspipe->pipe_ndx);
+
 	/* save original base layer */
 	ctrl->baselayer[mixer] = bspipe;
 
@@ -2091,17 +2096,18 @@
 	num = pipe->pipe_num;
 	ndx = pipe->pipe_ndx;
 	mixer = pipe->mixer_num;
-	iom = pipe->iommu;
 
 	mdp4_overlay_iommu_pipe_free(pipe->pipe_ndx, 0);
 
-	memset(pipe, 0, sizeof(*pipe));
+	iom = pipe->iommu;
 
+	memset(pipe, 0, sizeof(*pipe));
 	pipe->pipe_type = ptype;
 	pipe->pipe_num = num;
 	pipe->pipe_ndx = ndx;
 	pipe->mixer_num = mixer;
 	pipe->iommu = iom;
+
 }
 
 static int mdp4_overlay_validate_downscale(struct mdp_overlay *req,
diff --git a/drivers/video/msm/mdp4_overlay_dsi_cmd.c b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
index 7998d8b..1781344 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_cmd.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
@@ -751,7 +751,6 @@
 	if (pipe->pipe_used == 0 ||
 			pipe->mixer_stage != MDP4_MIXER_STAGE_BASE) {
 		pr_err("%s: NOT baselayer\n", __func__);
-		mutex_unlock(&mfd->dma->ov_mutex);
 		return;
 	}
 
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index e02e79c..d0d4f40 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -75,6 +75,7 @@
 	int blt_change;
 	int fake_vsync;
 	struct mutex update_lock;
+	struct completion ov_comp;
 	struct completion dmae_comp;
 	struct completion vsync_comp;
 	spinlock_t spin_lock;
@@ -160,6 +161,7 @@
 	*pp = *pipe;	/* keep it */
 	vp->update_cnt++;
 	mutex_unlock(&vctrl->update_lock);
+	mdp4_stat.overlay_play[pipe->mixer_num]++;
 }
 
 static void mdp4_dtv_blt_ov_update(struct mdp4_overlay_pipe *pipe);
@@ -198,6 +200,11 @@
 		if (pipe->pipe_used) {
 			cnt++;
 			mdp4_overlay_vsync_commit(pipe);
+			/* free previous iommu to freelist
+			* which will be freed at next
+			* pipe_commit
+			*/
+			mdp4_overlay_iommu_pipe_free(pipe->pipe_ndx, 0);
 			pipe->pipe_used = 0; /* clear */
 		}
 	}
@@ -216,10 +223,11 @@
 		outpdw(MDP_BASE + 0x0008, 0);
 	} else if (vctrl->dmae_intr_cnt == 0) {
 		/* schedule second phase update  at dmap */
-		vctrl->dmae_intr_cnt++;
+		INIT_COMPLETION(vctrl->dmae_comp);
 		vsync_irq_enable(INTR_DMA_E_DONE, MDP_DMA_E_TERM);
 	}
 	spin_unlock_irqrestore(&vctrl->spin_lock, flags);
+	mdp4_stat.overlay_commit[pipe->mixer_num]++;
 
 	return cnt;
 }
@@ -285,7 +293,6 @@
 
 static void mdp4_dtv_wait4dmae(int cndx)
 {
-	unsigned long flags;
 	struct vsycn_ctrl *vctrl;
 
 	if (cndx >= MAX_CONTROLLER) {
@@ -298,19 +305,7 @@
 	if (atomic_read(&vctrl->suspend) > 0)
 		return;
 
-	spin_lock_irqsave(&vctrl->spin_lock, flags);
-	if (vctrl->dmae_wait_cnt == 0) {
-		INIT_COMPLETION(vctrl->dmae_comp);
-		if (vctrl->dmae_intr_cnt == 0) {
-			vctrl->dmae_intr_cnt++;
-			vsync_irq_enable(INTR_DMA_E_DONE, MDP_DMA_E_TERM);
-		}
-	}
-	vctrl->dmae_wait_cnt++;
-	spin_unlock_irqrestore(&vctrl->spin_lock, flags);
-
 	wait_for_completion(&vctrl->dmae_comp);
-	pr_info("%s: pid=%d after wait\n", __func__, current->pid);
 }
 
 static void send_vsync_work(struct work_struct *work)
@@ -346,6 +341,8 @@
 	vctrl->update_ndx = 0;
 	mutex_init(&vctrl->update_lock);
 	init_completion(&vctrl->vsync_comp);
+	init_completion(&vctrl->ov_comp);
+	init_completion(&vctrl->dmae_comp);
 	atomic_set(&vctrl->suspend, 0);
 	spin_lock_init(&vctrl->spin_lock);
 	INIT_WORK(&vctrl->vsync_work, send_vsync_work);
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 18ec3f1..2c1f5b7 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -1772,8 +1772,7 @@
 	if (mfd->msmfb_no_update_notify_timer.function)
 		del_timer(&mfd->msmfb_no_update_notify_timer);
 
-	mfd->msmfb_no_update_notify_timer.expires =
-				jiffies + ((1000 * HZ) / 1000);
+	mfd->msmfb_no_update_notify_timer.expires = jiffies + (2 * HZ);
 	add_timer(&mfd->msmfb_no_update_notify_timer);
 	mutex_unlock(&msm_fb_notify_update_sem);
 
@@ -2961,8 +2960,7 @@
 	if (mfd->msmfb_no_update_notify_timer.function)
 		del_timer(&mfd->msmfb_no_update_notify_timer);
 
-	mfd->msmfb_no_update_notify_timer.expires =
-				jiffies + ((1000 * HZ) / 1000);
+	mfd->msmfb_no_update_notify_timer.expires = jiffies + (2 * HZ);
 	add_timer(&mfd->msmfb_no_update_notify_timer);
 	mutex_unlock(&msm_fb_notify_update_sem);
 
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index b6064a4..ac35780 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -15,6 +15,7 @@
 
 #include <linux/device.h>
 
+
 /* Peripheral id registers (0xFD0-0xFEC) */
 #define CORESIGHT_PERIPHIDR4	(0xFD0)
 #define CORESIGHT_PERIPHIDR5	(0xFD4)
@@ -30,6 +31,7 @@
 #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 */
@@ -150,36 +152,13 @@
 	const struct coresight_ops_source *source_ops;
 };
 
-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 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);
 extern void coresight_disable(struct coresight_device *csdev);
 #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 struct coresight_device *
 coresight_register(struct coresight_desc *desc) { return NULL; }
 static inline void coresight_unregister(struct coresight_device *csdev) {}
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 763e977..e731f97 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -363,6 +363,7 @@
 #define PHY_PWR_COLLAPSED		BIT(0)
 #define PHY_RETENTIONED			BIT(1)
 #define XO_SHUTDOWN			BIT(2)
+#define CLOCKS_DOWN			BIT(3)
 	int reset_counter;
 	unsigned long b_last_se0_sess;
 	unsigned long tmouts;
diff --git a/include/media/vcap_v4l2.h b/include/media/vcap_v4l2.h
index 390a843..cf99435 100644
--- a/include/media/vcap_v4l2.h
+++ b/include/media/vcap_v4l2.h
@@ -28,6 +28,7 @@
 #include <media/v4l2-common.h>
 #include <media/vcap_fmt.h>
 #include <mach/board.h>
+#include <mach/iommu_domains.h>
 
 #define to_client_data(val)     container_of(val, struct vcap_client_data, vfh)
 
@@ -94,7 +95,7 @@
 };
 
 struct nr_buffer {
-	void						*vaddr;
+	struct ion_handle			*nr_handle;
 	unsigned long				paddr;
 	enum nr_buf_pos				nr_pos;
 };
@@ -118,6 +119,7 @@
 
 	struct vcap_buffer      *bufOut;
 
+	struct ion_handle		*motionHandle;
 	void					*bufMotion;
 	struct nr_buffer		bufNR;
 	struct nr_param			nr_param;
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index 571e71c..59cb45b 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -3878,11 +3878,22 @@
 		}
 	} else if (dai->id == AIF1_CAP || dai->id == AIF2_CAP ||
 		   dai->id == AIF3_CAP) {
-		for (i = 0; i < tx_num; i++) {
-			tabla->dai[dai->id - 1].ch_num[i]  = tx_slot[i];
-			tabla->dai[dai->id - 1].ch_act = 0;
-			tabla->dai[dai->id - 1].ch_tot = tx_num;
+		tabla->dai[dai->id - 1].ch_tot = tx_num;
+		/* All channels are already active.
+		 * do not reset ch_act flag
+		 */
+		if ((tabla->dai[dai->id - 1].ch_tot != 0)
+			&& (tabla->dai[dai->id - 1].ch_act ==
+			tabla->dai[dai->id - 1].ch_tot)) {
+			pr_info("%s: ch_act = %d, ch_tot = %d\n", __func__,
+				tabla->dai[dai->id - 1].ch_act,
+				tabla->dai[dai->id - 1].ch_tot);
+			return 0;
 		}
+
+		tabla->dai[dai->id - 1].ch_act = 0;
+		for (i = 0; i < tx_num; i++)
+			tabla->dai[dai->id - 1].ch_num[i]  = tx_slot[i];
 	}
 	return 0;
 }
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index da3d335..26dbb21 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -1782,6 +1782,7 @@
 	.put = msm_routing_set_srs_trumedia_control,
 	.private_value = ((unsigned long)&(struct soc_mixer_control)
 	{.reg = SND_SOC_NOPM,
+	.rreg = SND_SOC_NOPM,
 	.shift = 0,
 	.rshift = 0,
 	.max = 0xFFFFFFFF,
@@ -1801,6 +1802,7 @@
 	.put = msm_routing_set_srs_trumedia_control_HDMI,
 	.private_value = ((unsigned long)&(struct soc_mixer_control)
 	{.reg = SND_SOC_NOPM,
+	.rreg = SND_SOC_NOPM,
 	.shift = 0,
 	.rshift = 0,
 	.max = 0xFFFFFFFF,
@@ -1820,6 +1822,7 @@
 	.put = msm_routing_set_srs_trumedia_control_I2S,
 	.private_value = ((unsigned long)&(struct soc_mixer_control)
 	{.reg = SND_SOC_NOPM,
+	.rreg = SND_SOC_NOPM,
 	.shift = 0,
 	.rshift = 0,
 	.max = 0xFFFFFFFF,
diff --git a/sound/soc/msm/qdsp6/q6voice.c b/sound/soc/msm/qdsp6/q6voice.c
index 3791f24..2a21dfa 100644
--- a/sound/soc/msm/qdsp6/q6voice.c
+++ b/sound/soc/msm/qdsp6/q6voice.c
@@ -36,10 +36,16 @@
 #define VOC_PATH_VOLTE_PASSIVE 2
 #define VOC_PATH_SGLTE_PASSIVE 3
 
-/* CVP CAL Size: 245760 = 240 * 1024 */
-#define CVP_CAL_SIZE 245760
-/* CVS CAL Size: 49152 = 48 * 1024 */
-#define CVS_CAL_SIZE 49152
+#define CAL_BUFFER_SIZE		4096
+#define NUM_CVP_CAL_BLOCKS	75
+#define NUM_CVS_CAL_BLOCKS	15
+#define CVP_CAL_SIZE		(NUM_CVP_CAL_BLOCKS * CAL_BUFFER_SIZE)
+#define CVS_CAL_SIZE		(NUM_CVS_CAL_BLOCKS * CAL_BUFFER_SIZE)
+#define VOICE_CAL_BUFFER_SIZE	(CVP_CAL_SIZE + CVS_CAL_SIZE)
+/* Total cal needed to support concurrent VOIP & VOLTE sessions */
+/* Due to memory map issue on Q6 separate memory has to be used */
+/* for VOIP & VOLTE  */
+#define TOTAL_VOICE_CAL_SIZE	(NUM_VOICE_CAL_BUFFERS * VOICE_CAL_BUFFER_SIZE)
 
 static struct common_data common;
 
@@ -198,6 +204,72 @@
 	return (session_id == common.voice[VOC_PATH_SGLTE_PASSIVE].session_id);
 }
 
+/* Only for memory allocated in the voice driver */
+/* which includes voip & volte */
+static int voice_get_cal_kernel_addr(int16_t session_id, int cal_type,
+					uint32_t *kvaddr)
+{
+	int	i, result = 0;
+	pr_debug("%s\n", __func__);
+
+	if (kvaddr == NULL) {
+		pr_err("%s: NULL pointer sent to function\n", __func__);
+		result = -EINVAL;
+		goto done;
+	} else if (is_voip_session(session_id)) {
+		i = VOIP_CAL;
+	} else if (is_volte_session(session_id)) {
+		i = VOLTE_CAL;
+	} else {
+		result = -EINVAL;
+		goto done;
+	}
+
+	if (common.voice_cal[i].cal_data[cal_type].kvaddr == 0) {
+		pr_err("%s: NULL pointer for session_id %d, type %d, cal_type %d\n",
+			__func__, session_id, i, cal_type);
+		result = -EFAULT;
+		goto done;
+	}
+
+	*kvaddr = common.voice_cal[i].cal_data[cal_type].kvaddr;
+done:
+	return result;
+}
+
+/* Only for memory allocated in the voice driver */
+/* which includes voip & volte */
+static int voice_get_cal_phys_addr(int16_t session_id, int cal_type,
+					uint32_t *paddr)
+{
+	int	i, result = 0;
+	pr_debug("%s\n", __func__);
+
+	if (paddr == NULL) {
+		pr_err("%s: NULL pointer sent to function\n", __func__);
+		result = -EINVAL;
+		goto done;
+	} else if (is_voip_session(session_id)) {
+		i = VOIP_CAL;
+	} else if (is_volte_session(session_id)) {
+		i = VOLTE_CAL;
+	} else {
+		result = -EINVAL;
+		goto done;
+	}
+
+	if (common.voice_cal[i].cal_data[cal_type].paddr == 0) {
+		pr_err("%s: No addr for session_id %d, type %d, cal_type %d\n",
+			__func__, session_id, i, cal_type);
+		result = -EFAULT;
+		goto done;
+	}
+
+	*paddr = common.voice_cal[i].cal_data[cal_type].paddr;
+done:
+	return result;
+}
+
 static int voice_apr_register(void)
 {
 	pr_debug("%s\n", __func__);
@@ -1237,7 +1309,8 @@
 	int ret = 0;
 	void *apr_cvs;
 	u16 cvs_handle;
-	uint32_t cal_paddr;
+	uint32_t cal_paddr = 0;
+	uint32_t cal_buf = 0;
 
 	/* get the cvs cal data */
 	get_all_vocstrm_cal(&cal_block);
@@ -1255,16 +1328,20 @@
 		return -EINVAL;
 	}
 
-	if (is_voip_session(v->session_id)) {
-		if (common.cvs_cal.buf) {
-			cal_paddr = common.cvs_cal.phy;
+	if (is_volte_session(v->session_id) ||
+			is_voip_session(v->session_id)) {
+		ret = voice_get_cal_phys_addr(v->session_id, CVS_CAL,
+						&cal_paddr);
+		if (ret < 0)
+			return ret;
 
-			memcpy(common.cvs_cal.buf,
-				(void *) cal_block.cal_kvaddr,
-				cal_block.cal_size);
-		} else {
-			return -EINVAL;
-		}
+		ret = voice_get_cal_kernel_addr(v->session_id, CVS_CAL,
+						&cal_buf);
+		if (ret < 0)
+			return ret;
+
+		memcpy((void *)cal_buf, (void *)cal_block.cal_kvaddr,
+			cal_block.cal_size);
 	} else {
 		cal_paddr = cal_block.cal_paddr;
 	}
@@ -1364,7 +1441,7 @@
 	int ret = 0;
 	void *apr_cvp;
 	u16 cvp_handle;
-	uint32_t cal_paddr;
+	uint32_t cal_paddr = 0;
 
 	/* get all cvp cal data */
 	get_all_cvp_cal(&cal_block);
@@ -1382,14 +1459,16 @@
 		return -EINVAL;
 	}
 
-	if (is_voip_session(v->session_id)) {
-		if (common.cvp_cal.buf)
-			cal_paddr = common.cvp_cal.phy;
-		else
-			return -EINVAL;
+	if (is_volte_session(v->session_id) ||
+			is_voip_session(v->session_id)) {
+		ret = voice_get_cal_phys_addr(v->session_id, CVP_CAL,
+						&cal_paddr);
+		if (ret < 0)
+			return ret;
 	} else {
 		cal_paddr = cal_block.cal_paddr;
 	}
+
 	cvp_handle = voice_get_cvp_handle(v);
 
 	/* fill in the header */
@@ -1402,7 +1481,7 @@
 	cvp_map_mem_cmd.hdr.token = 0;
 	cvp_map_mem_cmd.hdr.opcode = VSS_ICOMMON_CMD_MAP_MEMORY;
 
-	pr_debug("%s, phy_addr:0x%x, mem_size:%d\n", __func__,
+	pr_debug("%s, phys_addr: 0x%x, mem_size: %d\n", __func__,
 		cal_paddr, cal_block.cal_size);
 	cvp_map_mem_cmd.vss_map_mem.phys_addr = cal_paddr;
 	cvp_map_mem_cmd.vss_map_mem.mem_size = cal_block.cal_size;
@@ -1435,7 +1514,7 @@
 	int ret = 0;
 	void *apr_cvp;
 	u16 cvp_handle;
-	uint32_t cal_paddr;
+	uint32_t cal_paddr = 0;
 
 	get_all_cvp_cal(&cal_block);
 	if (cal_block.cal_size == 0)
@@ -1452,10 +1531,15 @@
 		return -EINVAL;
 	}
 
-	if (is_voip_session(v->session_id))
-		cal_paddr = common.cvp_cal.phy;
-	else
+	if (is_volte_session(v->session_id) ||
+			is_voip_session(v->session_id)) {
+		ret = voice_get_cal_phys_addr(v->session_id, CVP_CAL,
+						&cal_paddr);
+		if (ret < 0)
+			return ret;
+	} else {
 		cal_paddr = cal_block.cal_paddr;
+	}
 
 	cvp_handle = voice_get_cvp_handle(v);
 
@@ -1497,7 +1581,7 @@
 	int ret = 0;
 	void *apr_cvs;
 	u16 cvs_handle;
-	uint32_t cal_paddr;
+	uint32_t cal_paddr = 0;
 
 	/* get all cvs cal data */
 	get_all_vocstrm_cal(&cal_block);
@@ -1515,11 +1599,12 @@
 		return -EINVAL;
 	}
 
-	if (is_voip_session(v->session_id)) {
-		if (common.cvs_cal.buf)
-			cal_paddr = common.cvs_cal.phy;
-		else
-			return -EINVAL;
+	if (is_volte_session(v->session_id) ||
+			is_voip_session(v->session_id)) {
+		ret = voice_get_cal_phys_addr(v->session_id, CVS_CAL,
+						&cal_paddr);
+		if (ret < 0)
+			return ret;
 	} else {
 		cal_paddr = cal_block.cal_paddr;
 	}
@@ -1569,7 +1654,7 @@
 	int ret = 0;
 	void *apr_cvs;
 	u16 cvs_handle;
-	uint32_t cal_paddr;
+	uint32_t cal_paddr = 0;
 
 	get_all_vocstrm_cal(&cal_block);
 	if (cal_block.cal_size == 0)
@@ -1586,10 +1671,15 @@
 		return -EINVAL;
 	}
 
-	if (is_voip_session(v->session_id))
-		cal_paddr = common.cvs_cal.phy;
-	else
+	if (is_volte_session(v->session_id) ||
+			is_voip_session(v->session_id)) {
+		ret = voice_get_cal_phys_addr(v->session_id, CVS_CAL,
+						&cal_paddr);
+		if (ret < 0)
+			return ret;
+	} else {
 		cal_paddr = cal_block.cal_paddr;
+	}
 
 	cvs_handle = voice_get_cvs_handle(v);
 
@@ -1631,7 +1721,8 @@
 	int ret = 0;
 	void *apr_cvp;
 	u16 cvp_handle;
-	uint32_t cal_paddr;
+	uint32_t cal_paddr = 0;
+	uint32_t cal_buf = 0;
 
       /* get the cvp cal data */
 	get_all_vocproc_cal(&cal_block);
@@ -1649,16 +1740,20 @@
 		return -EINVAL;
 	}
 
-	if (is_voip_session(v->session_id)) {
-		if (common.cvp_cal.buf) {
-			cal_paddr = common.cvp_cal.phy;
+	if (is_volte_session(v->session_id) ||
+			is_voip_session(v->session_id)) {
+		ret = voice_get_cal_phys_addr(v->session_id, CVP_CAL,
+						&cal_paddr);
+		if (ret < 0)
+			return ret;
 
-			memcpy(common.cvp_cal.buf,
-				(void *)cal_block.cal_kvaddr,
-				cal_block.cal_size);
-		} else {
-			return -EINVAL;
-		}
+		ret = voice_get_cal_kernel_addr(v->session_id, CVP_CAL,
+						&cal_buf);
+		if (ret < 0)
+			return ret;
+
+		memcpy((void *)cal_buf, (void *)cal_block.cal_kvaddr,
+			cal_block.cal_size);
 	} else {
 		cal_paddr = cal_block.cal_paddr;
 	}
@@ -1759,7 +1854,8 @@
 	int ret = 0;
 	void *apr_cvp;
 	u16 cvp_handle;
-	uint32_t cal_paddr;
+	uint32_t cal_paddr = 0;
+	uint32_t cal_buf = 0;
 
 	/* get the cvp vol cal data */
 	get_all_vocvol_cal(&vol_block);
@@ -1779,16 +1875,21 @@
 		return -EINVAL;
 	}
 
-	if (is_voip_session(v->session_id)) {
-		if (common.cvp_cal.buf) {
-			cal_paddr = common.cvp_cal.phy + voc_block.cal_size;
+	if (is_volte_session(v->session_id) ||
+			is_voip_session(v->session_id)) {
+		ret = voice_get_cal_phys_addr(v->session_id, CVP_CAL,
+						&cal_paddr);
+		if (ret < 0)
+			return ret;
 
-			memcpy(common.cvp_cal.buf + voc_block.cal_size,
-				(void *) vol_block.cal_kvaddr,
-				vol_block.cal_size);
-		} else {
-			return -EINVAL;
-		}
+		cal_paddr += voc_block.cal_size;
+		ret = voice_get_cal_kernel_addr(v->session_id, CVP_CAL,
+						&cal_buf);
+		if (ret < 0)
+			return ret;
+
+		memcpy((void *)(cal_buf + voc_block.cal_size),
+			(void *)vol_block.cal_kvaddr, vol_block.cal_size);
 	} else {
 		cal_paddr = vol_block.cal_paddr;
 	}
@@ -3943,76 +4044,83 @@
 }
 
 
+static void voice_allocate_shared_memory(void)
+{
+	int			i, j, result;
+	int			offset = 0;
+	int			mem_len;
+	unsigned long		paddr;
+	void                    *kvptr;
+	pr_debug("%s\n", __func__);
+
+	common.ion_client = msm_ion_client_create(UINT_MAX, "q6voice_client");
+	if (IS_ERR_OR_NULL((void *)common.ion_client)) {
+		pr_err("%s: ION create client failed\n", __func__);
+		goto err;
+	}
+
+	common.ion_handle = ion_alloc(common.ion_client,
+				TOTAL_VOICE_CAL_SIZE,
+				SZ_4K, ION_HEAP(ION_AUDIO_HEAP_ID));
+	if (IS_ERR_OR_NULL((void *) common.ion_handle)) {
+		pr_err("%s: ION memory allocation failed\n",
+			__func__);
+		goto err_ion_client;
+	}
+
+	result = ion_phys(common.ion_client, common.ion_handle,
+			&paddr, (size_t *)&mem_len);
+	if (result) {
+		pr_err("%s: ION Get Physical failed, rc = %d\n",
+			__func__, result);
+		goto err_ion_handle;
+	}
+
+	kvptr = ion_map_kernel(common.ion_client,
+				common.ion_handle, 0);
+	if (IS_ERR_OR_NULL(kvptr)) {
+		pr_err("%s: ION memory mapping failed\n", __func__);
+		goto err_ion_handle;
+	}
+
+	/* Make all phys & buf point to the correct address */
+	for (i = 0; i < NUM_VOICE_CAL_BUFFERS; i++) {
+		for (j = 0; j < NUM_VOICE_CAL_TYPES; j++) {
+			common.voice_cal[i].cal_data[j].paddr =
+				(uint32_t)(paddr + offset);
+			common.voice_cal[i].cal_data[j].kvaddr =
+				(uint32_t)((uint8_t *)kvptr + offset);
+			if (j == CVP_CAL)
+				offset += CVP_CAL_SIZE;
+			else
+				offset += CVS_CAL_SIZE;
+
+			pr_debug("%s: kernel addr = 0x%x, phys addr = 0x%x\n",
+				__func__,
+				common.voice_cal[i].cal_data[j].kvaddr,
+				common.voice_cal[i].cal_data[j].paddr);
+		}
+	}
+
+	return;
+
+err_ion_handle:
+	ion_free(common.ion_client, common.ion_handle);
+err_ion_client:
+	ion_client_destroy(common.ion_client);
+err:
+	return;
+}
+
 static int __init voice_init(void)
 {
 	int rc = 0, i = 0;
-	int len;
 
 	memset(&common, 0, sizeof(struct common_data));
 
-	/* Allocate memory for VoIP calibration */
-	common.client = msm_ion_client_create(UINT_MAX, "voip_client");
-	if (IS_ERR_OR_NULL((void *)common.client)) {
-		pr_err("%s: ION create client for Voip failed\n", __func__);
-		goto cont;
-	}
-	common.cvp_cal.handle = ion_alloc(common.client, CVP_CAL_SIZE, SZ_4K,
-					  ION_HEAP(ION_AUDIO_HEAP_ID));
-	if (IS_ERR_OR_NULL((void *) common.cvp_cal.handle)) {
-		pr_err("%s: ION memory allocation for CVP failed\n",
-			__func__);
-		ion_client_destroy(common.client);
-		goto cont;
-	}
+	/* Allocate shared memory */
+	voice_allocate_shared_memory();
 
-	rc = ion_phys(common.client, common.cvp_cal.handle,
-		  (ion_phys_addr_t *)&common.cvp_cal.phy, (size_t *)&len);
-	if (rc) {
-		pr_err("%s: ION Get Physical for cvp failed, rc = %d\n",
-			__func__, rc);
-		ion_free(common.client, common.cvp_cal.handle);
-		ion_client_destroy(common.client);
-		goto cont;
-	}
-
-	common.cvp_cal.buf = ion_map_kernel(common.client,
-					common.cvp_cal.handle, 0);
-	if (IS_ERR_OR_NULL((void *) common.cvp_cal.buf)) {
-		pr_err("%s: ION memory mapping for cvp failed\n", __func__);
-		common.cvp_cal.buf = NULL;
-		ion_free(common.client, common.cvp_cal.handle);
-		ion_client_destroy(common.client);
-		goto cont;
-	}
-	memset((void *)common.cvp_cal.buf, 0, CVP_CAL_SIZE);
-
-	common.cvs_cal.handle = ion_alloc(common.client, CVS_CAL_SIZE, SZ_4K,
-					 ION_HEAP(ION_AUDIO_HEAP_ID));
-	if (IS_ERR_OR_NULL((void *) common.cvs_cal.handle)) {
-		pr_err("%s: ION memory allocation for CVS failed\n",
-			__func__);
-		goto cont;
-	}
-
-	rc = ion_phys(common.client, common.cvs_cal.handle,
-		  (ion_phys_addr_t *)&common.cvs_cal.phy, (size_t *)&len);
-	if (rc) {
-		pr_err("%s: ION Get Physical for cvs failed, rc = %d\n",
-			__func__, rc);
-		ion_free(common.client, common.cvs_cal.handle);
-		goto cont;
-	}
-
-	common.cvs_cal.buf = ion_map_kernel(common.client,
-					common.cvs_cal.handle, 0);
-	if (IS_ERR_OR_NULL((void *) common.cvs_cal.buf)) {
-		pr_err("%s: ION memory mapping for cvs failed\n", __func__);
-		common.cvs_cal.buf = NULL;
-		ion_free(common.client, common.cvs_cal.handle);
-		goto cont;
-	}
-	memset((void *)common.cvs_cal.buf, 0, CVS_CAL_SIZE);
-cont:
 	/* set default value */
 	common.default_mute_val = 0;  /* default is un-mute */
 	common.default_vol_val = 0;
diff --git a/sound/soc/msm/qdsp6/q6voice.h b/sound/soc/msm/qdsp6/q6voice.h
index 468aba8..1cb2878 100644
--- a/sound/soc/msm/qdsp6/q6voice.h
+++ b/sound/soc/msm/qdsp6/q6voice.h
@@ -22,6 +22,20 @@
 #define VOC_REC_DOWNLINK	0x01
 #define VOC_REC_BOTH		0x02
 
+/* Needed for VOIP & VOLTE support */
+/* Due to Q6 memory map issue */
+enum {
+	VOIP_CAL,
+	VOLTE_CAL,
+	NUM_VOICE_CAL_BUFFERS
+};
+
+enum {
+	CVP_CAL,
+	CVS_CAL,
+	NUM_VOICE_CAL_TYPES
+};
+
 struct voice_header {
 	uint32_t id;
 	uint32_t data_len;
@@ -913,9 +927,14 @@
 };
 
 struct cal_mem {
-	struct ion_handle *handle;
-	uint32_t phy;
-	void *buf;
+	/* Physical Address */
+	uint32_t paddr;
+	/* Kernel Virtual Address */
+	uint32_t kvaddr;
+};
+
+struct cal_data {
+	struct cal_mem	cal_data[NUM_VOICE_CAL_TYPES];
 };
 
 #define MAX_VOC_SESSIONS 4
@@ -934,9 +953,9 @@
 	/* APR to CVP in the Q6 */
 	void *apr_q6_cvp;
 
-	struct ion_client *client;
-	struct cal_mem cvp_cal;
-	struct cal_mem cvs_cal;
+	struct ion_client *ion_client;
+	struct ion_handle *ion_handle;
+	struct cal_data voice_cal[NUM_VOICE_CAL_BUFFERS];
 
 	struct mutex common_lock;
 
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index be2e0c5..2d2b333 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -700,7 +700,7 @@
 	if (perf_pmu__config(pmu, &attr, head_config))
 		return -EINVAL;
 
-	return add_event(list, idx, &attr, (char *) "pmu");
+	return add_event(list, idx, &attr, pmu->name);
 }
 
 void parse_events_update_lists(struct list_head *list_event,
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index 28e5548..4b3a3c9 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -64,7 +64,7 @@
 num_dec		[0-9]+
 num_hex		0x[a-fA-F0-9]+
 num_raw_hex	[a-fA-F0-9]+
-name		[a-zA-Z_*?][a-zA-Z0-9_*?]*
+name		[a-zA-Z_*?][a-zA-Z\-0-9_*?]*
 modifier_event	[ukhpGH]{1,8}
 modifier_bp	[rwx]