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(®ion_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(®ion_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), ®_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]