All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] coresight: next
@ 2015-02-27 23:04 ` Mathieu Poirier
  0 siblings, 0 replies; 28+ messages in thread
From: Mathieu Poirier @ 2015-02-27 23:04 UTC (permalink / raw)
  To: gregkh; +Cc: linux-arm-kernel, linux-kernel, zhang.chunyan, kaixu.xia

These are the latest coresight patches that I'd like you to consider for
inclusion in your tree.  The set is based on v4.0-rc1.

Thanks,
Mathieu

Mathieu Poirier (4):
  coresight: making cpu index lookup arm64 compliant
  coresight: fixing compilation warnings picked up by 64bit compiler
  coresight: Adding coresight support for arm64 architecture
  coresight-stm: Bindings for System Trace Macrocell

Pratik Patel (1):
  coresight-stm: adding driver for CoreSight STM component

 .../ABI/testing/sysfs-bus-coresight-devices-stm    |   62 ++
 .../devicetree/bindings/arm/coresight.txt          |   28 +
 Documentation/trace/coresight.txt                  |   88 +-
 arch/arm/Kconfig.debug                             |   55 +-
 arch/arm64/Kconfig.debug                           |    2 +
 drivers/coresight/Kconfig                          |   71 ++
 drivers/coresight/Makefile                         |    1 +
 drivers/coresight/coresight-etb10.c                |    4 +-
 drivers/coresight/coresight-stm.c                  | 1070 ++++++++++++++++++++
 drivers/coresight/coresight-tmc.c                  |    4 +-
 drivers/coresight/of_coresight.c                   |   18 +-
 include/linux/coresight-stm.h                      |   40 +
 include/uapi/linux/coresight-stm.h                 |   23 +
 13 files changed, 1394 insertions(+), 72 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-coresight-devices-stm
 create mode 100644 drivers/coresight/Kconfig
 create mode 100644 drivers/coresight/coresight-stm.c
 create mode 100644 include/linux/coresight-stm.h
 create mode 100644 include/uapi/linux/coresight-stm.h

-- 
1.9.1


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 0/5] coresight: next
@ 2015-02-27 23:04 ` Mathieu Poirier
  0 siblings, 0 replies; 28+ messages in thread
From: Mathieu Poirier @ 2015-02-27 23:04 UTC (permalink / raw)
  To: linux-arm-kernel

These are the latest coresight patches that I'd like you to consider for
inclusion in your tree.  The set is based on v4.0-rc1.

Thanks,
Mathieu

Mathieu Poirier (4):
  coresight: making cpu index lookup arm64 compliant
  coresight: fixing compilation warnings picked up by 64bit compiler
  coresight: Adding coresight support for arm64 architecture
  coresight-stm: Bindings for System Trace Macrocell

Pratik Patel (1):
  coresight-stm: adding driver for CoreSight STM component

 .../ABI/testing/sysfs-bus-coresight-devices-stm    |   62 ++
 .../devicetree/bindings/arm/coresight.txt          |   28 +
 Documentation/trace/coresight.txt                  |   88 +-
 arch/arm/Kconfig.debug                             |   55 +-
 arch/arm64/Kconfig.debug                           |    2 +
 drivers/coresight/Kconfig                          |   71 ++
 drivers/coresight/Makefile                         |    1 +
 drivers/coresight/coresight-etb10.c                |    4 +-
 drivers/coresight/coresight-stm.c                  | 1070 ++++++++++++++++++++
 drivers/coresight/coresight-tmc.c                  |    4 +-
 drivers/coresight/of_coresight.c                   |   18 +-
 include/linux/coresight-stm.h                      |   40 +
 include/uapi/linux/coresight-stm.h                 |   23 +
 13 files changed, 1394 insertions(+), 72 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-coresight-devices-stm
 create mode 100644 drivers/coresight/Kconfig
 create mode 100644 drivers/coresight/coresight-stm.c
 create mode 100644 include/linux/coresight-stm.h
 create mode 100644 include/uapi/linux/coresight-stm.h

-- 
1.9.1

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 1/5] coresight: making cpu index lookup arm64 compliant
  2015-02-27 23:04 ` Mathieu Poirier
@ 2015-02-27 23:04   ` Mathieu Poirier
  -1 siblings, 0 replies; 28+ messages in thread
From: Mathieu Poirier @ 2015-02-27 23:04 UTC (permalink / raw)
  To: gregkh; +Cc: linux-arm-kernel, linux-kernel, zhang.chunyan, kaixu.xia

Function "get_logical_index()" is not available on arm64.
Instead of adding the function simply using "of_get_cpu_node()" and
comparing the return value with cpu handles yields the same
result.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
 drivers/coresight/of_coresight.c | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/coresight/of_coresight.c b/drivers/coresight/of_coresight.c
index c3efa418a86d..f3cc8e97a0f8 100644
--- a/drivers/coresight/of_coresight.c
+++ b/drivers/coresight/of_coresight.c
@@ -22,6 +22,7 @@
 #include <linux/platform_device.h>
 #include <linux/amba/bus.h>
 #include <linux/coresight.h>
+#include <linux/cpumask.h>
 #include <asm/smp_plat.h>
 
 
@@ -113,7 +114,7 @@ static int of_coresight_alloc_memory(struct device *dev,
 struct coresight_platform_data *of_get_coresight_platform_data(
 				struct device *dev, struct device_node *node)
 {
-	int i = 0, ret = 0;
+	int i = 0, ret = 0, cpu;
 	struct coresight_platform_data *pdata;
 	struct of_endpoint endpoint, rendpoint;
 	struct device *rdev;
@@ -187,17 +188,10 @@ struct coresight_platform_data *of_get_coresight_platform_data(
 	/* Affinity defaults to CPU0 */
 	pdata->cpu = 0;
 	dn = of_parse_phandle(node, "cpu", 0);
-	if (dn) {
-		const u32 *cell;
-		int len, index;
-		u64 hwid;
-
-		cell = of_get_property(dn, "reg", &len);
-		if (cell) {
-			hwid = of_read_number(cell, of_n_addr_cells(dn));
-			index = get_logical_index(hwid);
-			if (index != -EINVAL)
-				pdata->cpu = index;
+	for (cpu = 0; dn && cpu < nr_cpu_ids; cpu++) {
+		if (dn == of_get_cpu_node(cpu, NULL)) {
+			pdata->cpu = cpu;
+			break;
 		}
 	}
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 1/5] coresight: making cpu index lookup arm64 compliant
@ 2015-02-27 23:04   ` Mathieu Poirier
  0 siblings, 0 replies; 28+ messages in thread
From: Mathieu Poirier @ 2015-02-27 23:04 UTC (permalink / raw)
  To: linux-arm-kernel

Function "get_logical_index()" is not available on arm64.
Instead of adding the function simply using "of_get_cpu_node()" and
comparing the return value with cpu handles yields the same
result.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
 drivers/coresight/of_coresight.c | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/drivers/coresight/of_coresight.c b/drivers/coresight/of_coresight.c
index c3efa418a86d..f3cc8e97a0f8 100644
--- a/drivers/coresight/of_coresight.c
+++ b/drivers/coresight/of_coresight.c
@@ -22,6 +22,7 @@
 #include <linux/platform_device.h>
 #include <linux/amba/bus.h>
 #include <linux/coresight.h>
+#include <linux/cpumask.h>
 #include <asm/smp_plat.h>
 
 
@@ -113,7 +114,7 @@ static int of_coresight_alloc_memory(struct device *dev,
 struct coresight_platform_data *of_get_coresight_platform_data(
 				struct device *dev, struct device_node *node)
 {
-	int i = 0, ret = 0;
+	int i = 0, ret = 0, cpu;
 	struct coresight_platform_data *pdata;
 	struct of_endpoint endpoint, rendpoint;
 	struct device *rdev;
@@ -187,17 +188,10 @@ struct coresight_platform_data *of_get_coresight_platform_data(
 	/* Affinity defaults to CPU0 */
 	pdata->cpu = 0;
 	dn = of_parse_phandle(node, "cpu", 0);
-	if (dn) {
-		const u32 *cell;
-		int len, index;
-		u64 hwid;
-
-		cell = of_get_property(dn, "reg", &len);
-		if (cell) {
-			hwid = of_read_number(cell, of_n_addr_cells(dn));
-			index = get_logical_index(hwid);
-			if (index != -EINVAL)
-				pdata->cpu = index;
+	for (cpu = 0; dn && cpu < nr_cpu_ids; cpu++) {
+		if (dn == of_get_cpu_node(cpu, NULL)) {
+			pdata->cpu = cpu;
+			break;
 		}
 	}
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 2/5] coresight: fixing compilation warnings picked up by 64bit compiler
  2015-02-27 23:04 ` Mathieu Poirier
@ 2015-02-27 23:04   ` Mathieu Poirier
  -1 siblings, 0 replies; 28+ messages in thread
From: Mathieu Poirier @ 2015-02-27 23:04 UTC (permalink / raw)
  To: gregkh; +Cc: linux-arm-kernel, linux-kernel, zhang.chunyan, kaixu.xia

Compiling coresight drivers with a 64-bit compiler highlights a couple
of formatting issues, which are fixed by this patch.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
 drivers/coresight/coresight-etb10.c | 4 ++--
 drivers/coresight/coresight-tmc.c   | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/coresight/coresight-etb10.c b/drivers/coresight/coresight-etb10.c
index c9acd406f0d0..40049869aecd 100644
--- a/drivers/coresight/coresight-etb10.c
+++ b/drivers/coresight/coresight-etb10.c
@@ -313,8 +313,8 @@ static ssize_t etb_read(struct file *file, char __user *data,
 
 	*ppos += len;
 
-	dev_dbg(drvdata->dev, "%s: %d bytes copied, %d bytes left\n",
-		__func__, len, (int) (depth * 4 - *ppos));
+	dev_dbg(drvdata->dev, "%s: %zu bytes copied, %d bytes left\n",
+		__func__, len, (int)(depth * 4 - *ppos));
 	return len;
 }
 
diff --git a/drivers/coresight/coresight-tmc.c b/drivers/coresight/coresight-tmc.c
index 3ff232f9ddf7..030e097c4fb2 100644
--- a/drivers/coresight/coresight-tmc.c
+++ b/drivers/coresight/coresight-tmc.c
@@ -533,8 +533,8 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
 
 	*ppos += len;
 
-	dev_dbg(drvdata->dev, "%s: %d bytes copied, %d bytes left\n",
-		__func__, len, (int) (drvdata->size - *ppos));
+	dev_dbg(drvdata->dev, "%s: %zu bytes copied, %d bytes left\n",
+		__func__, len, (int)(drvdata->size - *ppos));
 	return len;
 }
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 2/5] coresight: fixing compilation warnings picked up by 64bit compiler
@ 2015-02-27 23:04   ` Mathieu Poirier
  0 siblings, 0 replies; 28+ messages in thread
From: Mathieu Poirier @ 2015-02-27 23:04 UTC (permalink / raw)
  To: linux-arm-kernel

Compiling coresight drivers with a 64-bit compiler highlights a couple
of formatting issues, which are fixed by this patch.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
 drivers/coresight/coresight-etb10.c | 4 ++--
 drivers/coresight/coresight-tmc.c   | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/coresight/coresight-etb10.c b/drivers/coresight/coresight-etb10.c
index c9acd406f0d0..40049869aecd 100644
--- a/drivers/coresight/coresight-etb10.c
+++ b/drivers/coresight/coresight-etb10.c
@@ -313,8 +313,8 @@ static ssize_t etb_read(struct file *file, char __user *data,
 
 	*ppos += len;
 
-	dev_dbg(drvdata->dev, "%s: %d bytes copied, %d bytes left\n",
-		__func__, len, (int) (depth * 4 - *ppos));
+	dev_dbg(drvdata->dev, "%s: %zu bytes copied, %d bytes left\n",
+		__func__, len, (int)(depth * 4 - *ppos));
 	return len;
 }
 
diff --git a/drivers/coresight/coresight-tmc.c b/drivers/coresight/coresight-tmc.c
index 3ff232f9ddf7..030e097c4fb2 100644
--- a/drivers/coresight/coresight-tmc.c
+++ b/drivers/coresight/coresight-tmc.c
@@ -533,8 +533,8 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
 
 	*ppos += len;
 
-	dev_dbg(drvdata->dev, "%s: %d bytes copied, %d bytes left\n",
-		__func__, len, (int) (drvdata->size - *ppos));
+	dev_dbg(drvdata->dev, "%s: %zu bytes copied, %d bytes left\n",
+		__func__, len, (int)(drvdata->size - *ppos));
 	return len;
 }
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 3/5] coresight: Adding coresight support for arm64 architecture
  2015-02-27 23:04 ` Mathieu Poirier
@ 2015-02-27 23:04   ` Mathieu Poirier
  -1 siblings, 0 replies; 28+ messages in thread
From: Mathieu Poirier @ 2015-02-27 23:04 UTC (permalink / raw)
  To: gregkh; +Cc: linux-arm-kernel, linux-kernel, zhang.chunyan, kaixu.xia

Most CoreSight blocks are 64-bit ready.  As such move configuration
entries from "arch/arm/Kconfig.config" to the driver's subdirectory
and source the newly created Kconfig from architecture specific
Kconfig.debug files.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm/Kconfig.debug    | 55 +-----------------------------------------
 arch/arm64/Kconfig.debug  |  2 ++
 drivers/coresight/Kconfig | 61 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 64 insertions(+), 54 deletions(-)
 create mode 100644 drivers/coresight/Kconfig

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 970de7518341..8d14ad4e1db0 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -1610,59 +1610,6 @@ config DEBUG_SET_MODULE_RONX
 	  against certain classes of kernel exploits.
 	  If in doubt, say "N".
 
-menuconfig CORESIGHT
-	bool "CoreSight Tracing Support"
-	select ARM_AMBA
-	help
-	  This framework provides a kernel interface for the CoreSight debug
-	  and trace drivers to register themselves with. It's intended to build
-	  a topological view of the CoreSight components based on a DT
-	  specification and configure the right serie of components when a
-	  trace source gets enabled.
-
-if CORESIGHT
-config CORESIGHT_LINKS_AND_SINKS
-	bool "CoreSight Link and Sink drivers"
-	help
-	  This enables support for CoreSight link and sink drivers that are
-	  responsible for transporting and collecting the trace data
-	  respectively.  Link and sinks are dynamically aggregated with a trace
-	  entity at run time to form a complete trace path.
-
-config CORESIGHT_LINK_AND_SINK_TMC
-	bool "Coresight generic TMC driver"
-	depends on CORESIGHT_LINKS_AND_SINKS
-	help
-	  This enables support for the Trace Memory Controller driver.  Depending
-	  on its configuration the device can act as a link (embedded trace router
-	  - ETR) or sink (embedded trace FIFO).  The driver complies with the
-	  generic implementation of the component without special enhancement or
-	  added features.
-
-config CORESIGHT_SINK_TPIU
-	bool "Coresight generic TPIU driver"
-	depends on CORESIGHT_LINKS_AND_SINKS
-	help
-	  This enables support for the Trace Port Interface Unit driver, responsible
-	  for bridging the gap between the on-chip coresight components and a trace
-	  port collection engine, typically connected to an external host for use
-	  case capturing more traces than the on-board coresight memory can handle.
-
-config CORESIGHT_SINK_ETBV10
-	bool "Coresight ETBv1.0 driver"
-	depends on CORESIGHT_LINKS_AND_SINKS
-	help
-	  This enables support for the Embedded Trace Buffer version 1.0 driver
-	  that complies with the generic implementation of the component without
-	  special enhancement or added features.
+source "drivers/coresight/Kconfig"
 
-config CORESIGHT_SOURCE_ETM3X
-	bool "CoreSight Embedded Trace Macrocell 3.x driver"
-	select CORESIGHT_LINKS_AND_SINKS
-	help
-	  This driver provides support for processor ETM3.x and PTM1.x modules,
-	  which allows tracing the instructions that a processor is executing
-	  This is primarily useful for instruction level tracing.  Depending
-	  the ETM version data tracing may also be available.
-endif
 endmenu
diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug
index 4a8741073c90..5b2ffd8e6cdb 100644
--- a/arch/arm64/Kconfig.debug
+++ b/arch/arm64/Kconfig.debug
@@ -89,4 +89,6 @@ config DEBUG_ALIGN_RODATA
 
 	  If in doubt, say N
 
+source "drivers/coresight/Kconfig"
+
 endmenu
diff --git a/drivers/coresight/Kconfig b/drivers/coresight/Kconfig
new file mode 100644
index 000000000000..fc1f1ae7a49d
--- /dev/null
+++ b/drivers/coresight/Kconfig
@@ -0,0 +1,61 @@
+#
+# Coresight configuration
+#
+menuconfig CORESIGHT
+	bool "CoreSight Tracing Support"
+	select ARM_AMBA
+	help
+	  This framework provides a kernel interface for the CoreSight debug
+	  and trace drivers to register themselves with. It's intended to build
+	  a topological view of the CoreSight components based on a DT
+	  specification and configure the right serie of components when a
+	  trace source gets enabled.
+
+if CORESIGHT
+config CORESIGHT_LINKS_AND_SINKS
+	bool "CoreSight Link and Sink drivers"
+	help
+	  This enables support for CoreSight link and sink drivers that are
+	  responsible for transporting and collecting the trace data
+	  respectively.  Link and sinks are dynamically aggregated with a trace
+	  entity at run time to form a complete trace path.
+
+config CORESIGHT_LINK_AND_SINK_TMC
+	bool "Coresight generic TMC driver"
+	depends on CORESIGHT_LINKS_AND_SINKS
+	help
+	  This enables support for the Trace Memory Controller driver.
+	  Depending on its configuration the device can act as a link (embedded
+	  trace router - ETR) or sink (embedded trace FIFO).  The driver
+	  complies with the generic implementation of the component without
+	  special enhancement or added features.
+
+config CORESIGHT_SINK_TPIU
+	bool "Coresight generic TPIU driver"
+	depends on CORESIGHT_LINKS_AND_SINKS
+	help
+	  This enables support for the Trace Port Interface Unit driver,
+	  responsible for bridging the gap between the on-chip coresight
+	  components and a trace for bridging the gap between the on-chip
+	  coresight components and a trace port collection engine, typically
+	  connected to an external host for use case capturing more traces than
+	  the on-board coresight memory can handle.
+
+config CORESIGHT_SINK_ETBV10
+	bool "Coresight ETBv1.0 driver"
+	depends on CORESIGHT_LINKS_AND_SINKS
+	help
+	  This enables support for the Embedded Trace Buffer version 1.0 driver
+	  that complies with the generic implementation of the component without
+	  special enhancement or added features.
+
+config CORESIGHT_SOURCE_ETM3X
+	bool "CoreSight Embedded Trace Macrocell 3.x driver"
+	depends on !ARM64
+	select CORESIGHT_LINKS_AND_SINKS
+	help
+	  This driver provides support for processor ETM3.x and PTM1.x modules,
+	  which allows tracing the instructions that a processor is executing
+	  This is primarily useful for instruction level tracing.  Depending
+	  the ETM version data tracing may also be available.
+endif
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 3/5] coresight: Adding coresight support for arm64 architecture
@ 2015-02-27 23:04   ` Mathieu Poirier
  0 siblings, 0 replies; 28+ messages in thread
From: Mathieu Poirier @ 2015-02-27 23:04 UTC (permalink / raw)
  To: linux-arm-kernel

Most CoreSight blocks are 64-bit ready.  As such move configuration
entries from "arch/arm/Kconfig.config" to the driver's subdirectory
and source the newly created Kconfig from architecture specific
Kconfig.debug files.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm/Kconfig.debug    | 55 +-----------------------------------------
 arch/arm64/Kconfig.debug  |  2 ++
 drivers/coresight/Kconfig | 61 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 64 insertions(+), 54 deletions(-)
 create mode 100644 drivers/coresight/Kconfig

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 970de7518341..8d14ad4e1db0 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -1610,59 +1610,6 @@ config DEBUG_SET_MODULE_RONX
 	  against certain classes of kernel exploits.
 	  If in doubt, say "N".
 
-menuconfig CORESIGHT
-	bool "CoreSight Tracing Support"
-	select ARM_AMBA
-	help
-	  This framework provides a kernel interface for the CoreSight debug
-	  and trace drivers to register themselves with. It's intended to build
-	  a topological view of the CoreSight components based on a DT
-	  specification and configure the right serie of components when a
-	  trace source gets enabled.
-
-if CORESIGHT
-config CORESIGHT_LINKS_AND_SINKS
-	bool "CoreSight Link and Sink drivers"
-	help
-	  This enables support for CoreSight link and sink drivers that are
-	  responsible for transporting and collecting the trace data
-	  respectively.  Link and sinks are dynamically aggregated with a trace
-	  entity at run time to form a complete trace path.
-
-config CORESIGHT_LINK_AND_SINK_TMC
-	bool "Coresight generic TMC driver"
-	depends on CORESIGHT_LINKS_AND_SINKS
-	help
-	  This enables support for the Trace Memory Controller driver.  Depending
-	  on its configuration the device can act as a link (embedded trace router
-	  - ETR) or sink (embedded trace FIFO).  The driver complies with the
-	  generic implementation of the component without special enhancement or
-	  added features.
-
-config CORESIGHT_SINK_TPIU
-	bool "Coresight generic TPIU driver"
-	depends on CORESIGHT_LINKS_AND_SINKS
-	help
-	  This enables support for the Trace Port Interface Unit driver, responsible
-	  for bridging the gap between the on-chip coresight components and a trace
-	  port collection engine, typically connected to an external host for use
-	  case capturing more traces than the on-board coresight memory can handle.
-
-config CORESIGHT_SINK_ETBV10
-	bool "Coresight ETBv1.0 driver"
-	depends on CORESIGHT_LINKS_AND_SINKS
-	help
-	  This enables support for the Embedded Trace Buffer version 1.0 driver
-	  that complies with the generic implementation of the component without
-	  special enhancement or added features.
+source "drivers/coresight/Kconfig"
 
-config CORESIGHT_SOURCE_ETM3X
-	bool "CoreSight Embedded Trace Macrocell 3.x driver"
-	select CORESIGHT_LINKS_AND_SINKS
-	help
-	  This driver provides support for processor ETM3.x and PTM1.x modules,
-	  which allows tracing the instructions that a processor is executing
-	  This is primarily useful for instruction level tracing.  Depending
-	  the ETM version data tracing may also be available.
-endif
 endmenu
diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug
index 4a8741073c90..5b2ffd8e6cdb 100644
--- a/arch/arm64/Kconfig.debug
+++ b/arch/arm64/Kconfig.debug
@@ -89,4 +89,6 @@ config DEBUG_ALIGN_RODATA
 
 	  If in doubt, say N
 
+source "drivers/coresight/Kconfig"
+
 endmenu
diff --git a/drivers/coresight/Kconfig b/drivers/coresight/Kconfig
new file mode 100644
index 000000000000..fc1f1ae7a49d
--- /dev/null
+++ b/drivers/coresight/Kconfig
@@ -0,0 +1,61 @@
+#
+# Coresight configuration
+#
+menuconfig CORESIGHT
+	bool "CoreSight Tracing Support"
+	select ARM_AMBA
+	help
+	  This framework provides a kernel interface for the CoreSight debug
+	  and trace drivers to register themselves with. It's intended to build
+	  a topological view of the CoreSight components based on a DT
+	  specification and configure the right serie of components when a
+	  trace source gets enabled.
+
+if CORESIGHT
+config CORESIGHT_LINKS_AND_SINKS
+	bool "CoreSight Link and Sink drivers"
+	help
+	  This enables support for CoreSight link and sink drivers that are
+	  responsible for transporting and collecting the trace data
+	  respectively.  Link and sinks are dynamically aggregated with a trace
+	  entity at run time to form a complete trace path.
+
+config CORESIGHT_LINK_AND_SINK_TMC
+	bool "Coresight generic TMC driver"
+	depends on CORESIGHT_LINKS_AND_SINKS
+	help
+	  This enables support for the Trace Memory Controller driver.
+	  Depending on its configuration the device can act as a link (embedded
+	  trace router - ETR) or sink (embedded trace FIFO).  The driver
+	  complies with the generic implementation of the component without
+	  special enhancement or added features.
+
+config CORESIGHT_SINK_TPIU
+	bool "Coresight generic TPIU driver"
+	depends on CORESIGHT_LINKS_AND_SINKS
+	help
+	  This enables support for the Trace Port Interface Unit driver,
+	  responsible for bridging the gap between the on-chip coresight
+	  components and a trace for bridging the gap between the on-chip
+	  coresight components and a trace port collection engine, typically
+	  connected to an external host for use case capturing more traces than
+	  the on-board coresight memory can handle.
+
+config CORESIGHT_SINK_ETBV10
+	bool "Coresight ETBv1.0 driver"
+	depends on CORESIGHT_LINKS_AND_SINKS
+	help
+	  This enables support for the Embedded Trace Buffer version 1.0 driver
+	  that complies with the generic implementation of the component without
+	  special enhancement or added features.
+
+config CORESIGHT_SOURCE_ETM3X
+	bool "CoreSight Embedded Trace Macrocell 3.x driver"
+	depends on !ARM64
+	select CORESIGHT_LINKS_AND_SINKS
+	help
+	  This driver provides support for processor ETM3.x and PTM1.x modules,
+	  which allows tracing the instructions that a processor is executing
+	  This is primarily useful for instruction level tracing.  Depending
+	  the ETM version data tracing may also be available.
+endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 4/5] coresight-stm: adding driver for CoreSight STM component
  2015-02-27 23:04 ` Mathieu Poirier
@ 2015-02-27 23:04   ` Mathieu Poirier
  -1 siblings, 0 replies; 28+ messages in thread
From: Mathieu Poirier @ 2015-02-27 23:04 UTC (permalink / raw)
  To: gregkh; +Cc: linux-arm-kernel, linux-kernel, zhang.chunyan, kaixu.xia

From: Pratik Patel <pratikp@codeaurora.org>

This driver adds support for the STM CoreSight IP block,
allowing any system compoment (HW or SW) to log and
aggregate messages via a single entity.

The STM exposes an application defined number of channels
called stimulus port.  Configuration is done using entries
in sysfs and channels made available to userspace via devfs.

Signed-off-by: Pratik Patel <pratikp@codeaurora.org>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
 .../ABI/testing/sysfs-bus-coresight-devices-stm    |   62 ++
 Documentation/trace/coresight.txt                  |   88 +-
 drivers/coresight/Kconfig                          |   10 +
 drivers/coresight/Makefile                         |    1 +
 drivers/coresight/coresight-stm.c                  | 1070 ++++++++++++++++++++
 include/linux/coresight-stm.h                      |   40 +
 include/uapi/linux/coresight-stm.h                 |   23 +
 7 files changed, 1292 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-coresight-devices-stm
 create mode 100644 drivers/coresight/coresight-stm.c
 create mode 100644 include/linux/coresight-stm.h
 create mode 100644 include/uapi/linux/coresight-stm.h

diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-stm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-stm
new file mode 100644
index 000000000000..44fda9a47ea0
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-stm
@@ -0,0 +1,62 @@
+What:		/sys/bus/coresight/devices/<memory_map>.stm/enable_source
+Date:		February 2015
+KernelVersion:	4.01
+Contact:	Mathieu Poirier <mathieu.poirier@linaro.org>
+Description:	(RW) Enable/disable tracing on this specific trace macrocell.
+		Enabling the trace macrocell implies it has been configured
+		properly and a sink has been identidifed for it.  The path
+		of coresight components linking the source to the sink is
+		configured and managed automatically by the coresight framework.
+
+What:		/sys/bus/coresight/devices/<memory_map>.stm/entities
+Date:		February 2015
+KernelVersion:	4.01
+Contact:	Mathieu Poirier <mathieu.poirier@linaro.org>
+Description:	(RW) Controls which entities have been allowed to use the
+		stimulus ports, regarless of the channel they were assigned.
+		Entity definition can be found in
+		include/uapi/linux/coresight-stm32.h
+
+What:		/sys/bus/coresight/devices/<memory_map>.stm/hwevent_enable
+Date:		February 2015
+KernelVersion:	4.01
+Contact:	Mathieu Poirier <mathieu.poirier@linaro.org>
+Description:	(RW) Provides access to the HW event enable register, used in
+		conjunction with HW event bank select register.
+
+What:		/sys/bus/coresight/devices/<memory_map>.stm/hwevent_select
+Date:		February 2015
+KernelVersion:	4.01
+Contact:	Mathieu Poirier <mathieu.poirier@linaro.org>
+Description:	(RW) Gives access to the HW event block select register
+		(STMHEBSR) in order to configure up to 256 channels.  Used in
+		conjunction with "hwevent_enable" register as described above.
+
+What:		/sys/bus/coresight/devices/<memory_map>.stm/port_enable
+Date:		February 2015
+KernelVersion:	4.01
+Contact:	Mathieu Poirier <mathieu.poirier@linaro.org>
+Description:	(RW) Provides access to the stimlus port enable register
+		(STMSPER).  Used in conjunction with "port_select" described
+		below.
+
+What:		/sys/bus/coresight/devices/<memory_map>.stm/port_select
+Date:		February 2015
+KernelVersion:	4.01
+Contact:	Mathieu Poirier <mathieu.poirier@linaro.org>
+Description:	(RW) Used to determine which bank of stimulus port bit in
+		register STMSPER (see above) apply to.
+
+What:		/sys/bus/coresight/devices/<memory_map>.stm/status
+Date:		February 2015
+KernelVersion:	4.01
+Contact:	Mathieu Poirier <mathieu.poirier@linaro.org>
+Description:	(R) List various control and status registers.  The specific
+		layout and content is driver specific.
+
+What:		/sys/bus/coresight/devices/<memory_map>.stm/traceid
+Date:		February 2015
+KernelVersion:	4.01
+Contact:	Mathieu Poirier <mathieu.poirier@linaro.org>
+Description:	(RW) Holds the trace ID that will appear in the trace stream
+		coming from this trace entity.
diff --git a/Documentation/trace/coresight.txt b/Documentation/trace/coresight.txt
index 02361552a3ea..a041477698d9 100644
--- a/Documentation/trace/coresight.txt
+++ b/Documentation/trace/coresight.txt
@@ -190,8 +190,8 @@ expected to be accessed and controlled using those entries.
 Last but not least, "struct module *owner" is expected to be set to reflect
 the information carried in "THIS_MODULE".
 
-How to use
-----------
+How to use the tracer modules
+-----------------------------
 
 Before trace collection can start, a coresight sink needs to be identify.
 There is no limit on the amount of sinks (nor sources) that can be enabled at
@@ -297,3 +297,87 @@ Info                                    Tracing enabled
 Instruction     13570831        0x8026B584      E28DD00C        false   ADD      sp,sp,#0xc
 Instruction     0       0x8026B588      E8BD8000        true    LDM      sp!,{pc}
 Timestamp                                       Timestamp: 17107041535
+
+How to use the STM module
+-------------------------
+
+Using the System Trace Macrocell module is the same as the tracers - the only
+difference is that components (entities) are driving the trace capture rather
+than the program flow through the code.
+
+As with any other CoreSight component specifics about the STM tracer can be
+found in sysfs, with more information on each entry being found in [1]:
+
+root@genericarmv8:~# ls /sys/bus/coresight/devices/20100000.stm
+enable_source   hwevent_select  power           traceid
+entities        port_enable     status          uevent
+hwevent_enable  port_select     subsystem
+root@genericarmv8:~#
+
+Like any other source a sink needs to be identified and the STM enabled before
+being used:
+
+root@genericarmv8:~# echo 1 > /sys/bus/coresight/devices/20010000.etf/enable_sink
+root@genericarmv8:~# echo 1 > /sys/bus/coresight/devices/20100000.stm/enable_source
+
+From there user space applications can request and use channels using the devfs
+interface provided for that purpose:
+
+root@genericarmv8:~# ls -l /dev/20100000.stm
+crw-------    1 root     root       10,  61 Jan  3 18:11 /dev/20100000.stm
+root@genericarmv8:~#
+
+The following sample program provides an example of the supported operations:
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <linux/coresight-stm.h>
+
+#define BUFSIZE	20
+
+int main(int argc, char *argv[])
+{
+	int fd, n;
+	unsigned long options;
+	char buf[BUFSIZE];
+	char data[BUFSIZE] = "this is a test";
+
+	fd = open (argv[1], O_RDWR, 0);
+
+	if (n == -1) {
+		printf("can't open %s\n", argv[1]);
+		return 0;
+	}
+
+	n = read(fd, buf, BUFSIZE);
+	printf("channel_id: %d\n", atoi(buf));
+
+	options = STM_OPTION_TIMESTAMPED;
+	ioctl(fd, STM_IOCTL_SET_OPTIONS, &options);
+	options = 0;
+	ioctl(fd, STM_IOCTL_GET_OPTIONS, &options);
+	printf("options: 0x%x\n", options);
+
+	write(fd, data, strlen(data));
+
+	close(fd);
+
+	return 0;
+}
+
+When opening the devfs entry the first available channel is reserved for the
+requesting application.  That channel will remain the same until close() is
+called where it will go back to the channel pool.  From there calling open()
+again may or may _not_ yield the same channel number.
+
+From user space applications can determine what channel they've been given by
+issueing a read() on the file descriptor returned by open().  An ioctl() call is
+provided to set the channel options and the write() method will inject logging
+information in the channel.  There is no limit on the amount of channels an
+application can reserve, granted they use a different file descriptor for each
+one.
+
+If no more channels are available value of returned channel ID is '-1'.
+
+[1]. Documentation/ABI/testing/sysfs-bus-coresight-devices-stm
diff --git a/drivers/coresight/Kconfig b/drivers/coresight/Kconfig
index fc1f1ae7a49d..c865dcd306cd 100644
--- a/drivers/coresight/Kconfig
+++ b/drivers/coresight/Kconfig
@@ -58,4 +58,14 @@ config CORESIGHT_SOURCE_ETM3X
 	  which allows tracing the instructions that a processor is executing
 	  This is primarily useful for instruction level tracing.  Depending
 	  the ETM version data tracing may also be available.
+
+config CORESIGHT_STM
+	bool "CoreSight System Trace Macrocell driver"
+	depends on (ARM && !(CPU_32v3 || CPU_32v4 || CPU_32v4T)) || ARM64
+	select CORESIGHT_LINKS_AND_SINKS
+	help
+	  This driver provides support for hardware assisted software
+	  instrumentation based tracing. This is primarily used for
+	  logging useful software events or data coming from various entities
+	  in the system, possibly running different OSs
 endif
diff --git a/drivers/coresight/Makefile b/drivers/coresight/Makefile
index 4b4bec890ef5..7005b48a33ed 100644
--- a/drivers/coresight/Makefile
+++ b/drivers/coresight/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_CORESIGHT_SINK_ETBV10) += coresight-etb10.o
 obj-$(CONFIG_CORESIGHT_LINKS_AND_SINKS) += coresight-funnel.o \
 					   coresight-replicator.o
 obj-$(CONFIG_CORESIGHT_SOURCE_ETM3X) += coresight-etm3x.o coresight-etm-cp14.o
+obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o
diff --git a/drivers/coresight/coresight-stm.c b/drivers/coresight/coresight-stm.c
new file mode 100644
index 000000000000..61ab0c933eb5
--- /dev/null
+++ b/drivers/coresight/coresight-stm.c
@@ -0,0 +1,1070 @@
+/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/bitmap.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/coresight.h>
+#include <linux/coresight-stm.h>
+#include <linux/amba/bus.h>
+#include <asm/unaligned.h>
+
+#include "coresight-priv.h"
+
+#define STMDMASTARTR			0xc04
+#define STMDMASTOPR			0xc08
+#define STMDMASTATR			0xc0c
+#define STMDMACTLR			0xc10
+#define STMDMAIDR			0xcfc
+#define STMHEER				0xd00
+#define STMHETER			0xd20
+#define STMHEBSR			0xd60
+#define STMHEMCR			0xd64
+#define STMHEMASTR			0xdf4
+#define STMHEFEAT1R			0xdf8
+#define STMHEIDR			0xdfc
+#define STMSPER				0xe00
+#define STMSPTER			0xe20
+#define STMPRIVMASKR			0xe40
+#define STMSPSCR			0xe60
+#define STMSPMSCR			0xe64
+#define STMSPOVERRIDER			0xe68
+#define STMSPMOVERRIDER			0xe6c
+#define STMSPTRIGCSR			0xe70
+#define STMTCSR				0xe80
+#define STMTSSTIMR			0xe84
+#define STMTSFREQR			0xe8c
+#define STMSYNCR			0xe90
+#define STMAUXCR			0xe94
+#define STMSPFEAT1R			0xea0
+#define STMSPFEAT2R			0xea4
+#define STMSPFEAT3R			0xea8
+#define STMITTRIGGER			0xee8
+#define STMITATBDATA0			0xeec
+#define STMITATBCTR2			0xef0
+#define STMITATBID			0xef4
+#define STMITATBCTR0			0xef8
+
+#define STM_32_CHANNEL			32
+#define BYTES_PER_CHANNEL		256
+#define STM_TRACE_BUF_SIZE		4096
+
+/* Register bit definition */
+#define STMTCSR_BUSY_BIT		23
+/* Reserve the first 10 channels for kernel usage */
+#define STM_CHANNEL_OFFSET		0
+
+enum stm_pkt_type {
+	STM_PKT_TYPE_DATA	= 0x98,
+	STM_PKT_TYPE_FLAG	= 0xE8,
+	STM_PKT_TYPE_TRIG	= 0xF8,
+};
+
+enum {
+	STM_OPTION_MARKED	= 0x10,
+};
+
+#define stm_channel_addr(drvdata, ch)	(drvdata->chs.base +	\
+					(ch * BYTES_PER_CHANNEL))
+#define stm_channel_off(type, opts)	(type & ~opts)
+
+#ifndef CONFIG_64BIT
+static inline void __raw_writeq(u64 val, volatile void __iomem *addr)
+{
+	asm volatile("strd %1, %0"
+		     : "+Qo" (*(volatile u64 __force *)addr)
+		     : "r" (val));
+}
+#undef writeq_relaxed
+#define writeq_relaxed(v, c)	__raw_writeq((__force u64) cpu_to_le64(v), c)
+#endif
+
+static int boot_nr_channel;
+
+module_param_named(
+	boot_nr_channel, boot_nr_channel, int, S_IRUGO
+);
+
+/**
+ * struct channel_space - central management entity for extended ports
+ * @base:		memory mapped base address where channels start.
+ * @bitmap:		tally of which channel is being used.
+ */
+struct channel_space {
+	void __iomem		*base;
+	unsigned long		*bitmap;
+};
+
+/**
+ * struct stm_node - aggregation of channel information for userspace access
+ * @channel_id:		the channel number associated to this file descriptor.
+ * @options:		options for this channel - none, timestamped,
+ *			guaranteed.
+ * @drvdata:		STM driver specifics.
+ */
+struct stm_node {
+	int			channel_id;
+	u32			options;
+	struct stm_drvdata	*drvdata;
+};
+
+/**
+ * struct stm_drvdata - specifics associated to an STM component
+ * @ base:		memory mapped base address for this component.
+ * @dev:		the device entity associated to this component.
+ * @csdev:		component vitals needed by the framework.
+ * @miscdev:		specifics to handle "/dev/xyz.stm" entry.
+ * @clk:		the clock this component is associated to.
+ * @spinlock:		only one at a time pls.
+ * @chs:		the channels accociated to this STM.
+ * @enable:		this STM is being used.
+ * @entities:		set of entities allowed to access the STM ports.
+ * @traceid:		value of the current ID for this component.
+ * @write_64bit:	whether this STM supports 64 bit access.
+ * @stmsper:		settings for register STMSPER.
+ * @stmspscr:		settings for register STMSPSCR.
+ * @numsp:		the total number of stimulus port support by this STM.
+ * @stmheer:		settings for register STMHEER.
+ * @stmheter:		settings for register STMHETER.
+ * @stmhebsr:		settings for register STMHEBSR.
+ */
+struct stm_drvdata {
+	void __iomem		*base;
+	struct device		*dev;
+	struct coresight_device	*csdev;
+	struct miscdevice	miscdev;
+	struct clk		*clk;
+	spinlock_t		spinlock;
+	struct channel_space	chs;
+	bool			enable;
+	DECLARE_BITMAP(entities, STM_ENTITY_MAX);
+	u8			traceid;
+	u32			write_64bit;
+	u32			stmsper;
+	u32			stmspscr;
+	u32			numsp;
+	u32			stmheer;
+	u32			stmheter;
+	u32			stmhebsr;
+};
+
+static struct stm_drvdata *stmdrvdata;
+
+static void stm_hwevent_enable_hw(struct stm_drvdata *drvdata)
+{
+	CS_UNLOCK(drvdata->base);
+
+	writel_relaxed(drvdata->stmhebsr, drvdata->base + STMHEBSR);
+	writel_relaxed(drvdata->stmheter, drvdata->base + STMHETER);
+	writel_relaxed(drvdata->stmheer, drvdata->base + STMHEER);
+	writel_relaxed(0x01 |	/* Enable HW event tracing */
+		       0x04,	/* Error detection on event tracing */
+		       drvdata->base + STMHEMCR);
+
+	CS_LOCK(drvdata->base);
+}
+
+static void stm_port_enable_hw(struct stm_drvdata *drvdata)
+{
+	CS_UNLOCK(drvdata->base);
+	/* ATB trigger enable on direct writes to TRIG locations */
+	writel_relaxed(0x10,
+		       drvdata->base + STMSPTRIGCSR);
+	writel_relaxed(drvdata->stmspscr, drvdata->base + STMSPSCR);
+	writel_relaxed(drvdata->stmsper, drvdata->base + STMSPER);
+
+	CS_LOCK(drvdata->base);
+}
+
+static void stm_enable_hw(struct stm_drvdata *drvdata)
+{
+	if (drvdata->stmheer)
+		stm_hwevent_enable_hw(drvdata);
+
+	stm_port_enable_hw(drvdata);
+
+	CS_UNLOCK(drvdata->base);
+
+	/* 4096 byte between synchronisation packets */
+	writel_relaxed(0xFFF, drvdata->base + STMSYNCR);
+	writel_relaxed((drvdata->traceid << 16 | /* trace id */
+			0x02 |			 /* timestamp enable */
+			0x01),			 /* global STM enable */
+			drvdata->base + STMTCSR);
+
+	CS_LOCK(drvdata->base);
+}
+
+static int stm_enable(struct coresight_device *csdev)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+	int ret;
+
+	ret = clk_prepare_enable(drvdata->clk);
+	if (ret)
+		return ret;
+
+	spin_lock(&drvdata->spinlock);
+	stm_enable_hw(drvdata);
+	drvdata->enable = true;
+	spin_unlock(&drvdata->spinlock);
+
+	dev_info(drvdata->dev, "STM tracing enabled\n");
+	return 0;
+}
+
+static void stm_hwevent_disable_hw(struct stm_drvdata *drvdata)
+{
+	CS_UNLOCK(drvdata->base);
+
+	writel_relaxed(0x0, drvdata->base + STMHEMCR);
+	writel_relaxed(0x0, drvdata->base + STMHEER);
+	writel_relaxed(0x0, drvdata->base + STMHETER);
+
+	CS_LOCK(drvdata->base);
+}
+
+static void stm_port_disable_hw(struct stm_drvdata *drvdata)
+{
+	CS_UNLOCK(drvdata->base);
+
+	writel_relaxed(0x0, drvdata->base + STMSPER);
+	writel_relaxed(0x0, drvdata->base + STMSPTRIGCSR);
+
+	CS_LOCK(drvdata->base);
+}
+
+static void stm_disable_hw(struct stm_drvdata *drvdata)
+{
+	u32 val;
+
+	CS_UNLOCK(drvdata->base);
+
+	val = readl_relaxed(drvdata->base + STMTCSR);
+	val &= ~0x1; /* clear global STM enable [0] */
+	writel_relaxed(val, drvdata->base + STMTCSR);
+
+	CS_LOCK(drvdata->base);
+
+	stm_port_disable_hw(drvdata);
+	if (drvdata->stmheer)
+		stm_hwevent_disable_hw(drvdata);
+}
+
+static void stm_disable(struct coresight_device *csdev)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+	spin_lock(&drvdata->spinlock);
+	stm_disable_hw(drvdata);
+	drvdata->enable = false;
+	spin_unlock(&drvdata->spinlock);
+
+	/* Wait until the engine has completely stopped */
+	coresight_timeout(drvdata, STMTCSR, STMTCSR_BUSY_BIT, 0);
+
+	clk_disable_unprepare(drvdata->clk);
+
+	dev_info(drvdata->dev, "STM tracing disabled\n");
+}
+
+static int stm_trace_id(struct coresight_device *csdev)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+	return drvdata->traceid;
+}
+
+static const struct coresight_ops_source stm_source_ops = {
+	.trace_id	= stm_trace_id,
+	.enable		= stm_enable,
+	.disable	= stm_disable,
+};
+
+static const struct coresight_ops stm_cs_ops = {
+	.source_ops	= &stm_source_ops,
+};
+
+static int stm_channel_alloc(u32 off)
+{
+	struct stm_drvdata *drvdata = stmdrvdata;
+	int ch = -1;
+
+	do {
+		ch = find_next_zero_bit(drvdata->chs.bitmap,
+					drvdata->numsp, off);
+	} while ((ch < drvdata->numsp) &&
+		 test_and_set_bit(ch, drvdata->chs.bitmap));
+
+	return ch;
+}
+
+static void stm_channel_free(u32 ch)
+{
+	struct stm_drvdata *drvdata = stmdrvdata;
+
+	clear_bit(ch, drvdata->chs.bitmap);
+}
+
+static int stm_send_64bit(void *addr, const void *data, u32 size)
+{
+	u64 prepad = 0;
+	u64 postpad = 0;
+	char *pad;
+	u8 off, endoff;
+	u32 len = size;
+
+	off = (unsigned long)data & 0x7;
+
+	if (off) {
+		endoff = 8 - off;
+		pad = (char *)&prepad;
+		pad += off;
+
+		while (endoff && size) {
+			*pad++ = *(char *)data++;
+			endoff--;
+			size--;
+		}
+		writeq_relaxed(prepad, addr);
+	}
+
+	/* now we are 64bit aligned */
+	while (size >= 8) {
+		writeq_relaxed(*(u64 *)data, addr);
+		data += 8;
+		size -= 8;
+	}
+
+	endoff = 0;
+
+	if (size) {
+		endoff = 8 - (u8)size;
+		pad = (char *)&postpad;
+
+		while (size) {
+			*pad++ = *(char *)data++;
+			size--;
+		}
+		writeq_relaxed(postpad, addr);
+	}
+
+	return len + off + endoff;
+}
+
+static int stm_trace_data_64bit(unsigned long ch_addr, u32 options,
+				const void *data, u32 size)
+{
+	void *addr;
+
+	options &= ~STM_OPTION_TIMESTAMPED;
+	addr = (void *)(ch_addr | stm_channel_off(STM_PKT_TYPE_DATA, options));
+
+	return stm_send_64bit(addr, data, size);
+}
+
+static int stm_send(void *addr, const void *data, u32 size)
+{
+	u32 len = size;
+
+	if (((unsigned long)data & 0x1) && (size >= 1)) {
+		writeb_relaxed(*(u8 *)data, addr);
+		data++;
+		size--;
+	}
+	if (((unsigned long)data & 0x2) && (size >= 2)) {
+		writew_relaxed(*(u16 *)data, addr);
+		data += 2;
+		size -= 2;
+	}
+
+	/* now we are 32bit aligned */
+	while (size >= 4) {
+		writel_relaxed(*(u32 *)data, addr);
+		data += 4;
+		size -= 4;
+	}
+
+	if (size >= 2) {
+		writew_relaxed(*(u16 *)data, addr);
+		data += 2;
+		size -= 2;
+	}
+	if (size >= 1) {
+		writeb_relaxed(*(u8 *)data, addr);
+		data++;
+		size--;
+	}
+
+	return len;
+}
+
+static int stm_trace_data(unsigned long ch_addr, u32 options,
+			  const void *data, u32 size)
+{
+	void *addr;
+
+	options &= ~STM_OPTION_TIMESTAMPED;
+	addr = (void *)(ch_addr | stm_channel_off(STM_PKT_TYPE_DATA, options));
+
+	return stm_send(addr, data, size);
+}
+
+static inline int stm_trace_hw(u32 options, u32 channel, u8 entity_id,
+			       const void *data, u32 size)
+{
+	int len = 0;
+	unsigned long ch_addr;
+	struct stm_drvdata *drvdata = stmdrvdata;
+
+
+	/* get the channel address */
+	ch_addr = (unsigned long)stm_channel_addr(drvdata, channel);
+
+	if (drvdata->write_64bit)
+		len = stm_trace_data_64bit(ch_addr, options, data, size);
+	else
+		/* send the payload data */
+		len = stm_trace_data(ch_addr, options, data, size);
+
+	return len;
+}
+
+/**
+ * stm_trace - trace the binary or string data through STM
+ * @options: tracing options - guaranteed, timestamped, etc
+ * @entity_id: entity representing the trace data
+ * @data: pointer to binary r string data buffer
+ * @size: size of data to send
+ *
+ * Returns: number of bytes transferred over STM
+ */
+int stm_trace(u32 options, int channel_id,
+	      u8 entity_id, const void *data, u32 size)
+{
+	struct stm_drvdata *drvdata = stmdrvdata;
+
+	if (channel_id < 0)
+		return 0;
+
+	if (!(drvdata && drvdata->enable &&
+	      test_bit(entity_id, drvdata->entities)))
+		return 0;
+
+	return stm_trace_hw(options, (u32)channel_id,
+			    entity_id, data, size);
+}
+EXPORT_SYMBOL(stm_trace);
+
+static int stm_open(struct inode *inode, struct file *file)
+{
+	struct stm_node *node;
+	struct stm_drvdata *drvdata = container_of(file->private_data,
+						   struct stm_drvdata, miscdev);
+
+	node = kmalloc(sizeof(struct stm_node), GFP_KERNEL);
+	if (!node)
+		return -ENOMEM;
+
+	node->drvdata = drvdata;
+	node->options = STM_OPTION_TIMESTAMPED;
+	node->channel_id = stm_channel_alloc(STM_CHANNEL_OFFSET);
+	if (node->channel_id < 0)
+		return -ENOMEM;
+
+	file->private_data = node;
+	return 0;
+}
+
+static int stm_release(struct inode *inode, struct file *file)
+{
+	struct stm_node *node = file->private_data;
+
+	/* we are done, free the channel */
+	if (node->channel_id >= 0)
+		stm_channel_free((u32)node->channel_id);
+	file->private_data = NULL;
+	kfree(node);
+	return 0;
+}
+
+static ssize_t stm_read(struct file *file, char __user *data,
+			size_t size, loff_t *ppos)
+{
+	char buf[20];
+	struct stm_node *node = file->private_data;
+
+	snprintf(buf, sizeof(buf), "%d", node->channel_id);
+	return simple_read_from_buffer(data, size, ppos,
+				       buf, strlen(buf));
+}
+
+static ssize_t stm_write(struct file *file, const char __user *data,
+			 size_t size, loff_t *ppos)
+{
+	char *buf;
+	struct stm_node *node = file->private_data;
+	struct stm_drvdata *drvdata = node->drvdata;
+
+	if (node->channel_id < 0)
+		return -EINVAL;
+
+	if (!drvdata->enable || !size)
+		return -EINVAL;
+
+	if (size > STM_TRACE_BUF_SIZE)
+		size = STM_TRACE_BUF_SIZE;
+
+	buf = kmalloc(size, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	if (copy_from_user(buf, data, size)) {
+		kfree(buf);
+		dev_dbg(drvdata->dev, "%s: copy_from_user failed\n", __func__);
+		return -EFAULT;
+	}
+
+	if (!test_bit(STM_ENTITY_TRACE_USPACE, drvdata->entities)) {
+		kfree(buf);
+		return size;
+	}
+
+	stm_trace_hw(node->options, (u32)node->channel_id,
+		     STM_ENTITY_TRACE_USPACE, buf, size);
+
+	kfree(buf);
+
+	return size;
+}
+
+static long stm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	u32 options;
+	struct stm_node *node = file->private_data;
+
+	switch (cmd) {
+	case STM_IOCTL_SET_OPTIONS:
+		if (copy_from_user(&options, (void __user *)arg, sizeof(u32)))
+			return -EFAULT;
+
+		options &= (STM_OPTION_TIMESTAMPED | STM_OPTION_GUARANTEED);
+		node->options = options;
+		break;
+	case STM_IOCTL_GET_OPTIONS:
+		options = node->options;
+		if (copy_to_user((void __user *)arg, &options, sizeof(options)))
+			return -EFAULT;
+		break;
+	default:
+		return -EINVAL;
+	};
+
+	return 0;
+}
+
+static const struct file_operations stm_fops = {
+	.owner		= THIS_MODULE,
+	.open		= stm_open,
+	.write		= stm_write,
+	.read		= stm_read,
+	.llseek		= no_llseek,
+	.unlocked_ioctl	= stm_ioctl,
+	.release	= stm_release,
+};
+
+static ssize_t hwevent_enable_show(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val = drvdata->stmheer;
+
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t hwevent_enable_store(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t size)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val;
+	int ret = 0;
+
+	ret = kstrtoul(buf, 16, &val);
+	if (ret)
+		return -EINVAL;
+
+	drvdata->stmheer = val;
+	/* HW event enable and trigger go hand in hand */
+	drvdata->stmheter = val;
+
+	return size;
+}
+static DEVICE_ATTR_RW(hwevent_enable);
+
+static ssize_t hwevent_select_show(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val = drvdata->stmhebsr;
+
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t hwevent_select_store(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t size)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val;
+	int ret = 0;
+
+	ret = kstrtoul(buf, 16, &val);
+	if (ret)
+		return -EINVAL;
+
+	drvdata->stmhebsr = val;
+
+	return size;
+}
+static DEVICE_ATTR_RW(hwevent_select);
+
+static ssize_t port_select_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val;
+
+	if (!drvdata->enable) {
+		val = drvdata->stmspscr;
+	} else {
+		spin_lock(&drvdata->spinlock);
+		val = readl_relaxed(drvdata->base + STMSPSCR);
+		spin_unlock(&drvdata->spinlock);
+	}
+
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t port_select_store(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf, size_t size)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val, stmsper;
+	int ret = 0;
+
+	ret = kstrtoul(buf, 16, &val);
+	if (ret)
+		return ret;
+
+	spin_lock(&drvdata->spinlock);
+	drvdata->stmspscr = val;
+
+	if (drvdata->enable) {
+		CS_UNLOCK(drvdata->base);
+		/* Process as per ARM's TRM recommendation */
+		stmsper = readl_relaxed(drvdata->base + STMSPER);
+		writel_relaxed(0x0, drvdata->base + STMSPER);
+		writel_relaxed(drvdata->stmspscr, drvdata->base + STMSPSCR);
+		writel_relaxed(stmsper, drvdata->base + STMSPER);
+		CS_LOCK(drvdata->base);
+	}
+	spin_unlock(&drvdata->spinlock);
+
+	return size;
+}
+static DEVICE_ATTR_RW(port_select);
+
+static ssize_t port_enable_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val;
+
+	if (!drvdata->enable) {
+		val = drvdata->stmsper;
+	} else {
+		spin_lock(&drvdata->spinlock);
+		val = readl_relaxed(drvdata->base + STMSPER);
+		spin_unlock(&drvdata->spinlock);
+	}
+
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t port_enable_store(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf, size_t size)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val;
+	int ret = 0;
+
+	ret = kstrtoul(buf, 16, &val);
+	if (ret)
+		return ret;
+
+	spin_lock(&drvdata->spinlock);
+	drvdata->stmsper = val;
+
+	if (drvdata->enable) {
+		CS_UNLOCK(drvdata->base);
+		writel_relaxed(drvdata->stmsper, drvdata->base + STMSPER);
+		CS_LOCK(drvdata->base);
+	}
+	spin_unlock(&drvdata->spinlock);
+
+	return size;
+}
+static DEVICE_ATTR_RW(port_enable);
+
+static ssize_t entities_show(struct device *dev,
+			     struct device_attribute *attr, char *buf)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	ssize_t len;
+
+	len = scnprintf(buf, PAGE_SIZE, "%*pb",
+			STM_ENTITY_MAX, drvdata->entities);
+
+	if (PAGE_SIZE - len < 2)
+		len = -EINVAL;
+	else
+		len += scnprintf(buf + len, 2, "\n");
+
+	return len;
+}
+
+static ssize_t entities_store(struct device *dev,
+			      struct device_attribute *attr,
+			      const char *buf, size_t size)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val1, val2;
+
+	if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
+		return -EINVAL;
+
+	if (val1 >= STM_ENTITY_MAX)
+		return -EINVAL;
+
+	if (val2)
+		__set_bit(val1, drvdata->entities);
+	else
+		__clear_bit(val1, drvdata->entities);
+
+	return size;
+}
+static DEVICE_ATTR_RW(entities);
+
+static ssize_t status_show(struct device *dev,
+			   struct device_attribute *attr, char *buf)
+{
+	int ret;
+	unsigned long flags;
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	ret = clk_prepare_enable(drvdata->clk);
+	if (ret)
+		return ret;
+
+	spin_lock_irqsave(&drvdata->spinlock, flags);
+
+	CS_UNLOCK(drvdata->base);
+	ret = sprintf(buf,
+		      "STMTCSR:\t0x%08x\n"
+		      "STMTSFREQR:\t0x%08x\n"
+		      "STMTSYNCR:\t0x%08x\n"
+		      "STMSPER:\t0x%08x\n"
+		      "STMSPTER:\t0x%08x\n"
+		      "STMPRIVMASKR:\t0x%08x\n"
+		      "STMSPSCR:\t0x%08x\n"
+		      "STMSPMSCR:\t0x%08x\n"
+		      "STMFEAT1R:\t0x%08x\n"
+		      "STMFEAT2R:\t0x%08x\n"
+		      "STMFEAT3R:\t0x%08x\n"
+		      "STMDEVID:\t0x%08x\n",
+		      readl_relaxed(drvdata->base + STMTCSR),
+		      readl_relaxed(drvdata->base + STMTSFREQR),
+		      readl_relaxed(drvdata->base + STMSYNCR),
+		      readl_relaxed(drvdata->base + STMSPER),
+		      readl_relaxed(drvdata->base + STMSPTER),
+		      readl_relaxed(drvdata->base + STMPRIVMASKR),
+		      readl_relaxed(drvdata->base + STMSPSCR),
+		      readl_relaxed(drvdata->base + STMSPMSCR),
+		      readl_relaxed(drvdata->base + STMSPFEAT1R),
+		      readl_relaxed(drvdata->base + STMSPFEAT2R),
+		      readl_relaxed(drvdata->base + STMSPFEAT3R),
+		      readl_relaxed(drvdata->base + CORESIGHT_DEVID));
+
+	CS_LOCK(drvdata->base);
+	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	clk_disable_unprepare(drvdata->clk);
+
+	return ret;
+}
+static DEVICE_ATTR_RO(status);
+
+static ssize_t traceid_show(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	unsigned long val;
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	val = drvdata->traceid;
+	return sprintf(buf, "%#lx\n", val);
+}
+
+static ssize_t traceid_store(struct device *dev,
+			     struct device_attribute *attr,
+			     const char *buf, size_t size)
+{
+	int ret;
+	unsigned long val;
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	ret = kstrtoul(buf, 16, &val);
+	if (ret)
+		return ret;
+
+	/* traceid field is 7bit wide on STM32 */
+	drvdata->traceid = val & 0x7f;
+	return size;
+}
+static DEVICE_ATTR_RW(traceid);
+
+static struct attribute *coresight_stm_attrs[] = {
+	&dev_attr_hwevent_enable.attr,
+	&dev_attr_hwevent_select.attr,
+	&dev_attr_port_enable.attr,
+	&dev_attr_port_select.attr,
+	&dev_attr_entities.attr,
+	&dev_attr_status.attr,
+	&dev_attr_traceid.attr,
+	NULL,
+};
+ATTRIBUTE_GROUPS(coresight_stm);
+
+static int stm_get_resource_byname(struct device_node *np,
+				   char *ch_base, struct resource *res)
+{
+	const char *name = NULL;
+	int index = 0, found = 0;
+
+	while (!of_property_read_string_index(np, "reg-names", index, &name)) {
+		if (strcmp(ch_base, name)) {
+			index++;
+			continue;
+		}
+
+		/* We have a match and @index is where it's at */
+		found = 1;
+		break;
+	}
+
+	if (!found)
+		return -EINVAL;
+
+	return of_address_to_resource(np, index, res);
+}
+
+static u32 stm_fundamental_data_size(struct stm_drvdata *drvdata)
+{
+	u32 stmspfeat2r;
+
+	stmspfeat2r = readl_relaxed(drvdata->base + STMSPFEAT2R);
+	return BMVAL(stmspfeat2r, 12, 15);
+}
+
+static u32 stm_num_stimulus_port(struct stm_drvdata *drvdata)
+{
+	u32 numsp;
+
+	numsp = readl_relaxed(drvdata->base + CORESIGHT_DEVID);
+	/*
+	 * NUMPS in STMDEVID is 17 bit long and if equal to 0x0,
+	 * 32 stimulus ports are supported.
+	 */
+	numsp &= 0x1ffff;
+	if (!numsp)
+		numsp = STM_32_CHANNEL;
+	return numsp;
+}
+
+static void stm_init_default_data(struct stm_drvdata *drvdata)
+{
+	/* Don't use port selection */
+	drvdata->stmspscr = 0x0;
+	/*
+	 * Enable all channel regardless of their number.  When port
+	 * selection isn't used (see above) STMSPER applies to all
+	 * 32 channel group available, hence setting all 32 bits to 1
+	 */
+	drvdata->stmsper = ~0x0;
+
+	/*
+	 * Select arbitrary value to start with.  If there is a conflict
+	 * with other tracers the framework will deal with it.
+	 */
+	drvdata->traceid = 0x20;
+
+	bitmap_zero(drvdata->entities, STM_ENTITY_MAX);
+}
+
+static int stm_probe(struct amba_device *adev, const struct amba_id *id)
+{
+	int ret;
+	void __iomem *base;
+	unsigned long *bitmap;
+	struct device *dev = &adev->dev;
+	struct coresight_platform_data *pdata = NULL;
+	struct stm_drvdata *drvdata;
+	struct resource *res = &adev->res;
+	struct resource ch_res;
+	size_t res_size, bitmap_size;
+	struct coresight_desc *desc;
+	struct device_node *np = adev->dev.of_node;
+
+	if (np) {
+		pdata = of_get_coresight_platform_data(dev, np);
+		if (IS_ERR(pdata))
+			return PTR_ERR(pdata);
+		adev->dev.platform_data = pdata;
+	}
+	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata)
+		return -ENOMEM;
+
+	/* Store the driver data pointer for use in exported functions */
+	stmdrvdata = drvdata;
+	drvdata->dev = &adev->dev;
+	dev_set_drvdata(dev, drvdata);
+
+	base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+	drvdata->base = base;
+
+	ret = stm_get_resource_byname(np, "stm-stimulus-base", &ch_res);
+	if (ret)
+		return ret;
+
+	base = devm_ioremap_resource(dev, &ch_res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+	drvdata->chs.base = base;
+
+	ret = clk_prepare_enable(drvdata->clk);
+	if (ret)
+		return ret;
+
+	drvdata->write_64bit = stm_fundamental_data_size(drvdata);
+
+	if (boot_nr_channel) {
+		drvdata->numsp = boot_nr_channel;
+		res_size = min((resource_size_t)(boot_nr_channel *
+				  BYTES_PER_CHANNEL), resource_size(res));
+		bitmap_size = boot_nr_channel * sizeof(long);
+	} else {
+		drvdata->numsp = stm_num_stimulus_port(drvdata);
+		res_size = min((resource_size_t)(drvdata->numsp *
+				 BYTES_PER_CHANNEL), resource_size(res));
+		bitmap_size = drvdata->numsp * sizeof(long);
+	}
+
+	clk_disable_unprepare(drvdata->clk);
+
+	bitmap = devm_kzalloc(dev, bitmap_size, GFP_KERNEL);
+	if (!bitmap)
+		return -ENOMEM;
+	drvdata->chs.bitmap = bitmap;
+
+	spin_lock_init(&drvdata->spinlock);
+
+	drvdata->clk = adev->pclk;
+
+	stm_init_default_data(drvdata);
+
+	desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
+	if (!desc)
+		return -ENOMEM;
+
+	desc->type = CORESIGHT_DEV_TYPE_SOURCE;
+	desc->subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE;
+	desc->ops = &stm_cs_ops;
+	desc->pdata = pdata;
+	desc->dev = dev;
+	desc->groups = coresight_stm_groups;
+	drvdata->csdev = coresight_register(desc);
+	if (IS_ERR(drvdata->csdev))
+		return PTR_ERR(drvdata->csdev);
+
+	drvdata->miscdev.name = pdata->name;
+	drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
+	drvdata->miscdev.fops = &stm_fops;
+	ret = misc_register(&drvdata->miscdev);
+	if (ret)
+		goto err;
+
+	dev_info(drvdata->dev, "STM initialized\n");
+
+	return 0;
+err:
+	coresight_unregister(drvdata->csdev);
+	return ret;
+}
+
+static int stm_remove(struct amba_device *adev)
+{
+	struct stm_drvdata *drvdata = amba_get_drvdata(adev);
+
+	misc_deregister(&drvdata->miscdev);
+	coresight_unregister(drvdata->csdev);
+	return 0;
+}
+
+static struct amba_id stm_ids[] = {
+	{
+		.id     = 0x0003b962,
+		.mask   = 0x0003ffff,
+	},
+	{ 0, 0},
+};
+
+static struct amba_driver stm_driver = {
+	.drv = {
+		.name   = "coresight-stm",
+		.owner	= THIS_MODULE,
+	},
+	.probe          = stm_probe,
+	.remove         = stm_remove,
+	.id_table	= stm_ids,
+};
+
+module_amba_driver(stm_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("CoreSight System Trace Macrocell driver");
diff --git a/include/linux/coresight-stm.h b/include/linux/coresight-stm.h
new file mode 100644
index 000000000000..fc791562ad7c
--- /dev/null
+++ b/include/linux/coresight-stm.h
@@ -0,0 +1,40 @@
+#ifndef __LINUX_CORESIGHT_STM_H_
+#define __LINUX_CORESIGHT_STM_H_
+
+#include <uapi/linux/coresight-stm.h>
+
+/* kernel uses ch_id 0 until a better (more flexible) way is found */
+#define CH_ID_KERNEL	0
+
+#define stm_log_inv(entity_id, ch_id, data, size)		\
+	stm_trace(STM_OPTION_NONE, CH_ID_KERNEL,		\
+	STM_ENTITY_TRACE_KERNEL, data, size)
+
+#define stm_log_inv_ts(entity_id, ch_id, data, size)		\
+	stm_trace(STM_OPTION_TIMESTAMPED, CH_ID_KERNEL,		\
+	STM_ENTITY_TRACE_KERNEL, data, size)			\
+
+#define stm_log_gtd(entity_id, ch_id, data, size)		\
+	stm_trace(STM_OPTION_GUARANTEED, CH_ID_KERNEL,		\
+	STM_ENTITY_TRACE_KERNEL, data, size)			\
+
+#define stm_log_gtd_ts(entity_id, ch_id, data, size)		\
+	stm_trace(STM_OPTION_GUARANTEED |			\
+		  STM_OPTION_TIMESTAMPED,			\
+		  CH_ID_KERNEL, STM_ENTITY_TRACE_KERNEL, data, size)
+
+#define stm_log(entity_id, ch_id, data, size)			\
+	stm_log_inv_ts(entity_id, ch_id, data, size)
+
+#ifdef CONFIG_CORESIGHT_STM
+extern int stm_trace(u32 options, int channel_id,
+		     u8 entity_id, const void *data, u32 size);
+#else
+static inline int stm_trace(u32 options, int channel_id,
+			    u8 entity_id, const void *data, u32 size)
+{
+	return 0;
+}
+#endif
+
+#endif
diff --git a/include/uapi/linux/coresight-stm.h b/include/uapi/linux/coresight-stm.h
new file mode 100644
index 000000000000..208a4d79c4ee
--- /dev/null
+++ b/include/uapi/linux/coresight-stm.h
@@ -0,0 +1,23 @@
+#ifndef __UAPI_CORESIGHT_STM_H_
+#define __UAPI_CORESIGHT_STM_H_
+
+enum {
+	STM_ENTITY_NONE			= 0x00,
+	STM_ENTITY_TRACE_KERNEL		= 0x01,
+	STM_ENTITY_TRACE_USPACE		= 0x10,
+	STM_ENTITY_MAX			= 0xFF,
+};
+
+enum {
+	STM_IOCTL_NONE			= 0x00,
+	STM_IOCTL_SET_OPTIONS		= 0x01,
+	STM_IOCTL_GET_OPTIONS		= 0x10,
+};
+
+enum {
+	STM_OPTION_NONE			= 0x0,
+	STM_OPTION_TIMESTAMPED		= 0x08,
+	STM_OPTION_GUARANTEED		= 0x80,
+};
+
+#endif
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 4/5] coresight-stm: adding driver for CoreSight STM component
@ 2015-02-27 23:04   ` Mathieu Poirier
  0 siblings, 0 replies; 28+ messages in thread
From: Mathieu Poirier @ 2015-02-27 23:04 UTC (permalink / raw)
  To: linux-arm-kernel

From: Pratik Patel <pratikp@codeaurora.org>

This driver adds support for the STM CoreSight IP block,
allowing any system compoment (HW or SW) to log and
aggregate messages via a single entity.

The STM exposes an application defined number of channels
called stimulus port.  Configuration is done using entries
in sysfs and channels made available to userspace via devfs.

Signed-off-by: Pratik Patel <pratikp@codeaurora.org>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
---
 .../ABI/testing/sysfs-bus-coresight-devices-stm    |   62 ++
 Documentation/trace/coresight.txt                  |   88 +-
 drivers/coresight/Kconfig                          |   10 +
 drivers/coresight/Makefile                         |    1 +
 drivers/coresight/coresight-stm.c                  | 1070 ++++++++++++++++++++
 include/linux/coresight-stm.h                      |   40 +
 include/uapi/linux/coresight-stm.h                 |   23 +
 7 files changed, 1292 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-coresight-devices-stm
 create mode 100644 drivers/coresight/coresight-stm.c
 create mode 100644 include/linux/coresight-stm.h
 create mode 100644 include/uapi/linux/coresight-stm.h

diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-stm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-stm
new file mode 100644
index 000000000000..44fda9a47ea0
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-stm
@@ -0,0 +1,62 @@
+What:		/sys/bus/coresight/devices/<memory_map>.stm/enable_source
+Date:		February 2015
+KernelVersion:	4.01
+Contact:	Mathieu Poirier <mathieu.poirier@linaro.org>
+Description:	(RW) Enable/disable tracing on this specific trace macrocell.
+		Enabling the trace macrocell implies it has been configured
+		properly and a sink has been identidifed for it.  The path
+		of coresight components linking the source to the sink is
+		configured and managed automatically by the coresight framework.
+
+What:		/sys/bus/coresight/devices/<memory_map>.stm/entities
+Date:		February 2015
+KernelVersion:	4.01
+Contact:	Mathieu Poirier <mathieu.poirier@linaro.org>
+Description:	(RW) Controls which entities have been allowed to use the
+		stimulus ports, regarless of the channel they were assigned.
+		Entity definition can be found in
+		include/uapi/linux/coresight-stm32.h
+
+What:		/sys/bus/coresight/devices/<memory_map>.stm/hwevent_enable
+Date:		February 2015
+KernelVersion:	4.01
+Contact:	Mathieu Poirier <mathieu.poirier@linaro.org>
+Description:	(RW) Provides access to the HW event enable register, used in
+		conjunction with HW event bank select register.
+
+What:		/sys/bus/coresight/devices/<memory_map>.stm/hwevent_select
+Date:		February 2015
+KernelVersion:	4.01
+Contact:	Mathieu Poirier <mathieu.poirier@linaro.org>
+Description:	(RW) Gives access to the HW event block select register
+		(STMHEBSR) in order to configure up to 256 channels.  Used in
+		conjunction with "hwevent_enable" register as described above.
+
+What:		/sys/bus/coresight/devices/<memory_map>.stm/port_enable
+Date:		February 2015
+KernelVersion:	4.01
+Contact:	Mathieu Poirier <mathieu.poirier@linaro.org>
+Description:	(RW) Provides access to the stimlus port enable register
+		(STMSPER).  Used in conjunction with "port_select" described
+		below.
+
+What:		/sys/bus/coresight/devices/<memory_map>.stm/port_select
+Date:		February 2015
+KernelVersion:	4.01
+Contact:	Mathieu Poirier <mathieu.poirier@linaro.org>
+Description:	(RW) Used to determine which bank of stimulus port bit in
+		register STMSPER (see above) apply to.
+
+What:		/sys/bus/coresight/devices/<memory_map>.stm/status
+Date:		February 2015
+KernelVersion:	4.01
+Contact:	Mathieu Poirier <mathieu.poirier@linaro.org>
+Description:	(R) List various control and status registers.  The specific
+		layout and content is driver specific.
+
+What:		/sys/bus/coresight/devices/<memory_map>.stm/traceid
+Date:		February 2015
+KernelVersion:	4.01
+Contact:	Mathieu Poirier <mathieu.poirier@linaro.org>
+Description:	(RW) Holds the trace ID that will appear in the trace stream
+		coming from this trace entity.
diff --git a/Documentation/trace/coresight.txt b/Documentation/trace/coresight.txt
index 02361552a3ea..a041477698d9 100644
--- a/Documentation/trace/coresight.txt
+++ b/Documentation/trace/coresight.txt
@@ -190,8 +190,8 @@ expected to be accessed and controlled using those entries.
 Last but not least, "struct module *owner" is expected to be set to reflect
 the information carried in "THIS_MODULE".
 
-How to use
-----------
+How to use the tracer modules
+-----------------------------
 
 Before trace collection can start, a coresight sink needs to be identify.
 There is no limit on the amount of sinks (nor sources) that can be enabled at
@@ -297,3 +297,87 @@ Info                                    Tracing enabled
 Instruction     13570831        0x8026B584      E28DD00C        false   ADD      sp,sp,#0xc
 Instruction     0       0x8026B588      E8BD8000        true    LDM      sp!,{pc}
 Timestamp                                       Timestamp: 17107041535
+
+How to use the STM module
+-------------------------
+
+Using the System Trace Macrocell module is the same as the tracers - the only
+difference is that components (entities) are driving the trace capture rather
+than the program flow through the code.
+
+As with any other CoreSight component specifics about the STM tracer can be
+found in sysfs, with more information on each entry being found in [1]:
+
+root at genericarmv8:~# ls /sys/bus/coresight/devices/20100000.stm
+enable_source   hwevent_select  power           traceid
+entities        port_enable     status          uevent
+hwevent_enable  port_select     subsystem
+root at genericarmv8:~#
+
+Like any other source a sink needs to be identified and the STM enabled before
+being used:
+
+root at genericarmv8:~# echo 1 > /sys/bus/coresight/devices/20010000.etf/enable_sink
+root at genericarmv8:~# echo 1 > /sys/bus/coresight/devices/20100000.stm/enable_source
+
+From there user space applications can request and use channels using the devfs
+interface provided for that purpose:
+
+root at genericarmv8:~# ls -l /dev/20100000.stm
+crw-------    1 root     root       10,  61 Jan  3 18:11 /dev/20100000.stm
+root at genericarmv8:~#
+
+The following sample program provides an example of the supported operations:
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <linux/coresight-stm.h>
+
+#define BUFSIZE	20
+
+int main(int argc, char *argv[])
+{
+	int fd, n;
+	unsigned long options;
+	char buf[BUFSIZE];
+	char data[BUFSIZE] = "this is a test";
+
+	fd = open (argv[1], O_RDWR, 0);
+
+	if (n == -1) {
+		printf("can't open %s\n", argv[1]);
+		return 0;
+	}
+
+	n = read(fd, buf, BUFSIZE);
+	printf("channel_id: %d\n", atoi(buf));
+
+	options = STM_OPTION_TIMESTAMPED;
+	ioctl(fd, STM_IOCTL_SET_OPTIONS, &options);
+	options = 0;
+	ioctl(fd, STM_IOCTL_GET_OPTIONS, &options);
+	printf("options: 0x%x\n", options);
+
+	write(fd, data, strlen(data));
+
+	close(fd);
+
+	return 0;
+}
+
+When opening the devfs entry the first available channel is reserved for the
+requesting application.  That channel will remain the same until close() is
+called where it will go back to the channel pool.  From there calling open()
+again may or may _not_ yield the same channel number.
+
+From user space applications can determine what channel they've been given by
+issueing a read() on the file descriptor returned by open().  An ioctl() call is
+provided to set the channel options and the write() method will inject logging
+information in the channel.  There is no limit on the amount of channels an
+application can reserve, granted they use a different file descriptor for each
+one.
+
+If no more channels are available value of returned channel ID is '-1'.
+
+[1]. Documentation/ABI/testing/sysfs-bus-coresight-devices-stm
diff --git a/drivers/coresight/Kconfig b/drivers/coresight/Kconfig
index fc1f1ae7a49d..c865dcd306cd 100644
--- a/drivers/coresight/Kconfig
+++ b/drivers/coresight/Kconfig
@@ -58,4 +58,14 @@ config CORESIGHT_SOURCE_ETM3X
 	  which allows tracing the instructions that a processor is executing
 	  This is primarily useful for instruction level tracing.  Depending
 	  the ETM version data tracing may also be available.
+
+config CORESIGHT_STM
+	bool "CoreSight System Trace Macrocell driver"
+	depends on (ARM && !(CPU_32v3 || CPU_32v4 || CPU_32v4T)) || ARM64
+	select CORESIGHT_LINKS_AND_SINKS
+	help
+	  This driver provides support for hardware assisted software
+	  instrumentation based tracing. This is primarily used for
+	  logging useful software events or data coming from various entities
+	  in the system, possibly running different OSs
 endif
diff --git a/drivers/coresight/Makefile b/drivers/coresight/Makefile
index 4b4bec890ef5..7005b48a33ed 100644
--- a/drivers/coresight/Makefile
+++ b/drivers/coresight/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_CORESIGHT_SINK_ETBV10) += coresight-etb10.o
 obj-$(CONFIG_CORESIGHT_LINKS_AND_SINKS) += coresight-funnel.o \
 					   coresight-replicator.o
 obj-$(CONFIG_CORESIGHT_SOURCE_ETM3X) += coresight-etm3x.o coresight-etm-cp14.o
+obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o
diff --git a/drivers/coresight/coresight-stm.c b/drivers/coresight/coresight-stm.c
new file mode 100644
index 000000000000..61ab0c933eb5
--- /dev/null
+++ b/drivers/coresight/coresight-stm.c
@@ -0,0 +1,1070 @@
+/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/bitmap.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/coresight.h>
+#include <linux/coresight-stm.h>
+#include <linux/amba/bus.h>
+#include <asm/unaligned.h>
+
+#include "coresight-priv.h"
+
+#define STMDMASTARTR			0xc04
+#define STMDMASTOPR			0xc08
+#define STMDMASTATR			0xc0c
+#define STMDMACTLR			0xc10
+#define STMDMAIDR			0xcfc
+#define STMHEER				0xd00
+#define STMHETER			0xd20
+#define STMHEBSR			0xd60
+#define STMHEMCR			0xd64
+#define STMHEMASTR			0xdf4
+#define STMHEFEAT1R			0xdf8
+#define STMHEIDR			0xdfc
+#define STMSPER				0xe00
+#define STMSPTER			0xe20
+#define STMPRIVMASKR			0xe40
+#define STMSPSCR			0xe60
+#define STMSPMSCR			0xe64
+#define STMSPOVERRIDER			0xe68
+#define STMSPMOVERRIDER			0xe6c
+#define STMSPTRIGCSR			0xe70
+#define STMTCSR				0xe80
+#define STMTSSTIMR			0xe84
+#define STMTSFREQR			0xe8c
+#define STMSYNCR			0xe90
+#define STMAUXCR			0xe94
+#define STMSPFEAT1R			0xea0
+#define STMSPFEAT2R			0xea4
+#define STMSPFEAT3R			0xea8
+#define STMITTRIGGER			0xee8
+#define STMITATBDATA0			0xeec
+#define STMITATBCTR2			0xef0
+#define STMITATBID			0xef4
+#define STMITATBCTR0			0xef8
+
+#define STM_32_CHANNEL			32
+#define BYTES_PER_CHANNEL		256
+#define STM_TRACE_BUF_SIZE		4096
+
+/* Register bit definition */
+#define STMTCSR_BUSY_BIT		23
+/* Reserve the first 10 channels for kernel usage */
+#define STM_CHANNEL_OFFSET		0
+
+enum stm_pkt_type {
+	STM_PKT_TYPE_DATA	= 0x98,
+	STM_PKT_TYPE_FLAG	= 0xE8,
+	STM_PKT_TYPE_TRIG	= 0xF8,
+};
+
+enum {
+	STM_OPTION_MARKED	= 0x10,
+};
+
+#define stm_channel_addr(drvdata, ch)	(drvdata->chs.base +	\
+					(ch * BYTES_PER_CHANNEL))
+#define stm_channel_off(type, opts)	(type & ~opts)
+
+#ifndef CONFIG_64BIT
+static inline void __raw_writeq(u64 val, volatile void __iomem *addr)
+{
+	asm volatile("strd %1, %0"
+		     : "+Qo" (*(volatile u64 __force *)addr)
+		     : "r" (val));
+}
+#undef writeq_relaxed
+#define writeq_relaxed(v, c)	__raw_writeq((__force u64) cpu_to_le64(v), c)
+#endif
+
+static int boot_nr_channel;
+
+module_param_named(
+	boot_nr_channel, boot_nr_channel, int, S_IRUGO
+);
+
+/**
+ * struct channel_space - central management entity for extended ports
+ * @base:		memory mapped base address where channels start.
+ * @bitmap:		tally of which channel is being used.
+ */
+struct channel_space {
+	void __iomem		*base;
+	unsigned long		*bitmap;
+};
+
+/**
+ * struct stm_node - aggregation of channel information for userspace access
+ * @channel_id:		the channel number associated to this file descriptor.
+ * @options:		options for this channel - none, timestamped,
+ *			guaranteed.
+ * @drvdata:		STM driver specifics.
+ */
+struct stm_node {
+	int			channel_id;
+	u32			options;
+	struct stm_drvdata	*drvdata;
+};
+
+/**
+ * struct stm_drvdata - specifics associated to an STM component
+ * @ base:		memory mapped base address for this component.
+ * @dev:		the device entity associated to this component.
+ * @csdev:		component vitals needed by the framework.
+ * @miscdev:		specifics to handle "/dev/xyz.stm" entry.
+ * @clk:		the clock this component is associated to.
+ * @spinlock:		only one at a time pls.
+ * @chs:		the channels accociated to this STM.
+ * @enable:		this STM is being used.
+ * @entities:		set of entities allowed to access the STM ports.
+ * @traceid:		value of the current ID for this component.
+ * @write_64bit:	whether this STM supports 64 bit access.
+ * @stmsper:		settings for register STMSPER.
+ * @stmspscr:		settings for register STMSPSCR.
+ * @numsp:		the total number of stimulus port support by this STM.
+ * @stmheer:		settings for register STMHEER.
+ * @stmheter:		settings for register STMHETER.
+ * @stmhebsr:		settings for register STMHEBSR.
+ */
+struct stm_drvdata {
+	void __iomem		*base;
+	struct device		*dev;
+	struct coresight_device	*csdev;
+	struct miscdevice	miscdev;
+	struct clk		*clk;
+	spinlock_t		spinlock;
+	struct channel_space	chs;
+	bool			enable;
+	DECLARE_BITMAP(entities, STM_ENTITY_MAX);
+	u8			traceid;
+	u32			write_64bit;
+	u32			stmsper;
+	u32			stmspscr;
+	u32			numsp;
+	u32			stmheer;
+	u32			stmheter;
+	u32			stmhebsr;
+};
+
+static struct stm_drvdata *stmdrvdata;
+
+static void stm_hwevent_enable_hw(struct stm_drvdata *drvdata)
+{
+	CS_UNLOCK(drvdata->base);
+
+	writel_relaxed(drvdata->stmhebsr, drvdata->base + STMHEBSR);
+	writel_relaxed(drvdata->stmheter, drvdata->base + STMHETER);
+	writel_relaxed(drvdata->stmheer, drvdata->base + STMHEER);
+	writel_relaxed(0x01 |	/* Enable HW event tracing */
+		       0x04,	/* Error detection on event tracing */
+		       drvdata->base + STMHEMCR);
+
+	CS_LOCK(drvdata->base);
+}
+
+static void stm_port_enable_hw(struct stm_drvdata *drvdata)
+{
+	CS_UNLOCK(drvdata->base);
+	/* ATB trigger enable on direct writes to TRIG locations */
+	writel_relaxed(0x10,
+		       drvdata->base + STMSPTRIGCSR);
+	writel_relaxed(drvdata->stmspscr, drvdata->base + STMSPSCR);
+	writel_relaxed(drvdata->stmsper, drvdata->base + STMSPER);
+
+	CS_LOCK(drvdata->base);
+}
+
+static void stm_enable_hw(struct stm_drvdata *drvdata)
+{
+	if (drvdata->stmheer)
+		stm_hwevent_enable_hw(drvdata);
+
+	stm_port_enable_hw(drvdata);
+
+	CS_UNLOCK(drvdata->base);
+
+	/* 4096 byte between synchronisation packets */
+	writel_relaxed(0xFFF, drvdata->base + STMSYNCR);
+	writel_relaxed((drvdata->traceid << 16 | /* trace id */
+			0x02 |			 /* timestamp enable */
+			0x01),			 /* global STM enable */
+			drvdata->base + STMTCSR);
+
+	CS_LOCK(drvdata->base);
+}
+
+static int stm_enable(struct coresight_device *csdev)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+	int ret;
+
+	ret = clk_prepare_enable(drvdata->clk);
+	if (ret)
+		return ret;
+
+	spin_lock(&drvdata->spinlock);
+	stm_enable_hw(drvdata);
+	drvdata->enable = true;
+	spin_unlock(&drvdata->spinlock);
+
+	dev_info(drvdata->dev, "STM tracing enabled\n");
+	return 0;
+}
+
+static void stm_hwevent_disable_hw(struct stm_drvdata *drvdata)
+{
+	CS_UNLOCK(drvdata->base);
+
+	writel_relaxed(0x0, drvdata->base + STMHEMCR);
+	writel_relaxed(0x0, drvdata->base + STMHEER);
+	writel_relaxed(0x0, drvdata->base + STMHETER);
+
+	CS_LOCK(drvdata->base);
+}
+
+static void stm_port_disable_hw(struct stm_drvdata *drvdata)
+{
+	CS_UNLOCK(drvdata->base);
+
+	writel_relaxed(0x0, drvdata->base + STMSPER);
+	writel_relaxed(0x0, drvdata->base + STMSPTRIGCSR);
+
+	CS_LOCK(drvdata->base);
+}
+
+static void stm_disable_hw(struct stm_drvdata *drvdata)
+{
+	u32 val;
+
+	CS_UNLOCK(drvdata->base);
+
+	val = readl_relaxed(drvdata->base + STMTCSR);
+	val &= ~0x1; /* clear global STM enable [0] */
+	writel_relaxed(val, drvdata->base + STMTCSR);
+
+	CS_LOCK(drvdata->base);
+
+	stm_port_disable_hw(drvdata);
+	if (drvdata->stmheer)
+		stm_hwevent_disable_hw(drvdata);
+}
+
+static void stm_disable(struct coresight_device *csdev)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+	spin_lock(&drvdata->spinlock);
+	stm_disable_hw(drvdata);
+	drvdata->enable = false;
+	spin_unlock(&drvdata->spinlock);
+
+	/* Wait until the engine has completely stopped */
+	coresight_timeout(drvdata, STMTCSR, STMTCSR_BUSY_BIT, 0);
+
+	clk_disable_unprepare(drvdata->clk);
+
+	dev_info(drvdata->dev, "STM tracing disabled\n");
+}
+
+static int stm_trace_id(struct coresight_device *csdev)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+	return drvdata->traceid;
+}
+
+static const struct coresight_ops_source stm_source_ops = {
+	.trace_id	= stm_trace_id,
+	.enable		= stm_enable,
+	.disable	= stm_disable,
+};
+
+static const struct coresight_ops stm_cs_ops = {
+	.source_ops	= &stm_source_ops,
+};
+
+static int stm_channel_alloc(u32 off)
+{
+	struct stm_drvdata *drvdata = stmdrvdata;
+	int ch = -1;
+
+	do {
+		ch = find_next_zero_bit(drvdata->chs.bitmap,
+					drvdata->numsp, off);
+	} while ((ch < drvdata->numsp) &&
+		 test_and_set_bit(ch, drvdata->chs.bitmap));
+
+	return ch;
+}
+
+static void stm_channel_free(u32 ch)
+{
+	struct stm_drvdata *drvdata = stmdrvdata;
+
+	clear_bit(ch, drvdata->chs.bitmap);
+}
+
+static int stm_send_64bit(void *addr, const void *data, u32 size)
+{
+	u64 prepad = 0;
+	u64 postpad = 0;
+	char *pad;
+	u8 off, endoff;
+	u32 len = size;
+
+	off = (unsigned long)data & 0x7;
+
+	if (off) {
+		endoff = 8 - off;
+		pad = (char *)&prepad;
+		pad += off;
+
+		while (endoff && size) {
+			*pad++ = *(char *)data++;
+			endoff--;
+			size--;
+		}
+		writeq_relaxed(prepad, addr);
+	}
+
+	/* now we are 64bit aligned */
+	while (size >= 8) {
+		writeq_relaxed(*(u64 *)data, addr);
+		data += 8;
+		size -= 8;
+	}
+
+	endoff = 0;
+
+	if (size) {
+		endoff = 8 - (u8)size;
+		pad = (char *)&postpad;
+
+		while (size) {
+			*pad++ = *(char *)data++;
+			size--;
+		}
+		writeq_relaxed(postpad, addr);
+	}
+
+	return len + off + endoff;
+}
+
+static int stm_trace_data_64bit(unsigned long ch_addr, u32 options,
+				const void *data, u32 size)
+{
+	void *addr;
+
+	options &= ~STM_OPTION_TIMESTAMPED;
+	addr = (void *)(ch_addr | stm_channel_off(STM_PKT_TYPE_DATA, options));
+
+	return stm_send_64bit(addr, data, size);
+}
+
+static int stm_send(void *addr, const void *data, u32 size)
+{
+	u32 len = size;
+
+	if (((unsigned long)data & 0x1) && (size >= 1)) {
+		writeb_relaxed(*(u8 *)data, addr);
+		data++;
+		size--;
+	}
+	if (((unsigned long)data & 0x2) && (size >= 2)) {
+		writew_relaxed(*(u16 *)data, addr);
+		data += 2;
+		size -= 2;
+	}
+
+	/* now we are 32bit aligned */
+	while (size >= 4) {
+		writel_relaxed(*(u32 *)data, addr);
+		data += 4;
+		size -= 4;
+	}
+
+	if (size >= 2) {
+		writew_relaxed(*(u16 *)data, addr);
+		data += 2;
+		size -= 2;
+	}
+	if (size >= 1) {
+		writeb_relaxed(*(u8 *)data, addr);
+		data++;
+		size--;
+	}
+
+	return len;
+}
+
+static int stm_trace_data(unsigned long ch_addr, u32 options,
+			  const void *data, u32 size)
+{
+	void *addr;
+
+	options &= ~STM_OPTION_TIMESTAMPED;
+	addr = (void *)(ch_addr | stm_channel_off(STM_PKT_TYPE_DATA, options));
+
+	return stm_send(addr, data, size);
+}
+
+static inline int stm_trace_hw(u32 options, u32 channel, u8 entity_id,
+			       const void *data, u32 size)
+{
+	int len = 0;
+	unsigned long ch_addr;
+	struct stm_drvdata *drvdata = stmdrvdata;
+
+
+	/* get the channel address */
+	ch_addr = (unsigned long)stm_channel_addr(drvdata, channel);
+
+	if (drvdata->write_64bit)
+		len = stm_trace_data_64bit(ch_addr, options, data, size);
+	else
+		/* send the payload data */
+		len = stm_trace_data(ch_addr, options, data, size);
+
+	return len;
+}
+
+/**
+ * stm_trace - trace the binary or string data through STM
+ * @options: tracing options - guaranteed, timestamped, etc
+ * @entity_id: entity representing the trace data
+ * @data: pointer to binary r string data buffer
+ * @size: size of data to send
+ *
+ * Returns: number of bytes transferred over STM
+ */
+int stm_trace(u32 options, int channel_id,
+	      u8 entity_id, const void *data, u32 size)
+{
+	struct stm_drvdata *drvdata = stmdrvdata;
+
+	if (channel_id < 0)
+		return 0;
+
+	if (!(drvdata && drvdata->enable &&
+	      test_bit(entity_id, drvdata->entities)))
+		return 0;
+
+	return stm_trace_hw(options, (u32)channel_id,
+			    entity_id, data, size);
+}
+EXPORT_SYMBOL(stm_trace);
+
+static int stm_open(struct inode *inode, struct file *file)
+{
+	struct stm_node *node;
+	struct stm_drvdata *drvdata = container_of(file->private_data,
+						   struct stm_drvdata, miscdev);
+
+	node = kmalloc(sizeof(struct stm_node), GFP_KERNEL);
+	if (!node)
+		return -ENOMEM;
+
+	node->drvdata = drvdata;
+	node->options = STM_OPTION_TIMESTAMPED;
+	node->channel_id = stm_channel_alloc(STM_CHANNEL_OFFSET);
+	if (node->channel_id < 0)
+		return -ENOMEM;
+
+	file->private_data = node;
+	return 0;
+}
+
+static int stm_release(struct inode *inode, struct file *file)
+{
+	struct stm_node *node = file->private_data;
+
+	/* we are done, free the channel */
+	if (node->channel_id >= 0)
+		stm_channel_free((u32)node->channel_id);
+	file->private_data = NULL;
+	kfree(node);
+	return 0;
+}
+
+static ssize_t stm_read(struct file *file, char __user *data,
+			size_t size, loff_t *ppos)
+{
+	char buf[20];
+	struct stm_node *node = file->private_data;
+
+	snprintf(buf, sizeof(buf), "%d", node->channel_id);
+	return simple_read_from_buffer(data, size, ppos,
+				       buf, strlen(buf));
+}
+
+static ssize_t stm_write(struct file *file, const char __user *data,
+			 size_t size, loff_t *ppos)
+{
+	char *buf;
+	struct stm_node *node = file->private_data;
+	struct stm_drvdata *drvdata = node->drvdata;
+
+	if (node->channel_id < 0)
+		return -EINVAL;
+
+	if (!drvdata->enable || !size)
+		return -EINVAL;
+
+	if (size > STM_TRACE_BUF_SIZE)
+		size = STM_TRACE_BUF_SIZE;
+
+	buf = kmalloc(size, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	if (copy_from_user(buf, data, size)) {
+		kfree(buf);
+		dev_dbg(drvdata->dev, "%s: copy_from_user failed\n", __func__);
+		return -EFAULT;
+	}
+
+	if (!test_bit(STM_ENTITY_TRACE_USPACE, drvdata->entities)) {
+		kfree(buf);
+		return size;
+	}
+
+	stm_trace_hw(node->options, (u32)node->channel_id,
+		     STM_ENTITY_TRACE_USPACE, buf, size);
+
+	kfree(buf);
+
+	return size;
+}
+
+static long stm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	u32 options;
+	struct stm_node *node = file->private_data;
+
+	switch (cmd) {
+	case STM_IOCTL_SET_OPTIONS:
+		if (copy_from_user(&options, (void __user *)arg, sizeof(u32)))
+			return -EFAULT;
+
+		options &= (STM_OPTION_TIMESTAMPED | STM_OPTION_GUARANTEED);
+		node->options = options;
+		break;
+	case STM_IOCTL_GET_OPTIONS:
+		options = node->options;
+		if (copy_to_user((void __user *)arg, &options, sizeof(options)))
+			return -EFAULT;
+		break;
+	default:
+		return -EINVAL;
+	};
+
+	return 0;
+}
+
+static const struct file_operations stm_fops = {
+	.owner		= THIS_MODULE,
+	.open		= stm_open,
+	.write		= stm_write,
+	.read		= stm_read,
+	.llseek		= no_llseek,
+	.unlocked_ioctl	= stm_ioctl,
+	.release	= stm_release,
+};
+
+static ssize_t hwevent_enable_show(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val = drvdata->stmheer;
+
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t hwevent_enable_store(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t size)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val;
+	int ret = 0;
+
+	ret = kstrtoul(buf, 16, &val);
+	if (ret)
+		return -EINVAL;
+
+	drvdata->stmheer = val;
+	/* HW event enable and trigger go hand in hand */
+	drvdata->stmheter = val;
+
+	return size;
+}
+static DEVICE_ATTR_RW(hwevent_enable);
+
+static ssize_t hwevent_select_show(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val = drvdata->stmhebsr;
+
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t hwevent_select_store(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t size)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val;
+	int ret = 0;
+
+	ret = kstrtoul(buf, 16, &val);
+	if (ret)
+		return -EINVAL;
+
+	drvdata->stmhebsr = val;
+
+	return size;
+}
+static DEVICE_ATTR_RW(hwevent_select);
+
+static ssize_t port_select_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val;
+
+	if (!drvdata->enable) {
+		val = drvdata->stmspscr;
+	} else {
+		spin_lock(&drvdata->spinlock);
+		val = readl_relaxed(drvdata->base + STMSPSCR);
+		spin_unlock(&drvdata->spinlock);
+	}
+
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t port_select_store(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf, size_t size)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val, stmsper;
+	int ret = 0;
+
+	ret = kstrtoul(buf, 16, &val);
+	if (ret)
+		return ret;
+
+	spin_lock(&drvdata->spinlock);
+	drvdata->stmspscr = val;
+
+	if (drvdata->enable) {
+		CS_UNLOCK(drvdata->base);
+		/* Process as per ARM's TRM recommendation */
+		stmsper = readl_relaxed(drvdata->base + STMSPER);
+		writel_relaxed(0x0, drvdata->base + STMSPER);
+		writel_relaxed(drvdata->stmspscr, drvdata->base + STMSPSCR);
+		writel_relaxed(stmsper, drvdata->base + STMSPER);
+		CS_LOCK(drvdata->base);
+	}
+	spin_unlock(&drvdata->spinlock);
+
+	return size;
+}
+static DEVICE_ATTR_RW(port_select);
+
+static ssize_t port_enable_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val;
+
+	if (!drvdata->enable) {
+		val = drvdata->stmsper;
+	} else {
+		spin_lock(&drvdata->spinlock);
+		val = readl_relaxed(drvdata->base + STMSPER);
+		spin_unlock(&drvdata->spinlock);
+	}
+
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+
+static ssize_t port_enable_store(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf, size_t size)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val;
+	int ret = 0;
+
+	ret = kstrtoul(buf, 16, &val);
+	if (ret)
+		return ret;
+
+	spin_lock(&drvdata->spinlock);
+	drvdata->stmsper = val;
+
+	if (drvdata->enable) {
+		CS_UNLOCK(drvdata->base);
+		writel_relaxed(drvdata->stmsper, drvdata->base + STMSPER);
+		CS_LOCK(drvdata->base);
+	}
+	spin_unlock(&drvdata->spinlock);
+
+	return size;
+}
+static DEVICE_ATTR_RW(port_enable);
+
+static ssize_t entities_show(struct device *dev,
+			     struct device_attribute *attr, char *buf)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	ssize_t len;
+
+	len = scnprintf(buf, PAGE_SIZE, "%*pb",
+			STM_ENTITY_MAX, drvdata->entities);
+
+	if (PAGE_SIZE - len < 2)
+		len = -EINVAL;
+	else
+		len += scnprintf(buf + len, 2, "\n");
+
+	return len;
+}
+
+static ssize_t entities_store(struct device *dev,
+			      struct device_attribute *attr,
+			      const char *buf, size_t size)
+{
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val1, val2;
+
+	if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
+		return -EINVAL;
+
+	if (val1 >= STM_ENTITY_MAX)
+		return -EINVAL;
+
+	if (val2)
+		__set_bit(val1, drvdata->entities);
+	else
+		__clear_bit(val1, drvdata->entities);
+
+	return size;
+}
+static DEVICE_ATTR_RW(entities);
+
+static ssize_t status_show(struct device *dev,
+			   struct device_attribute *attr, char *buf)
+{
+	int ret;
+	unsigned long flags;
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	ret = clk_prepare_enable(drvdata->clk);
+	if (ret)
+		return ret;
+
+	spin_lock_irqsave(&drvdata->spinlock, flags);
+
+	CS_UNLOCK(drvdata->base);
+	ret = sprintf(buf,
+		      "STMTCSR:\t0x%08x\n"
+		      "STMTSFREQR:\t0x%08x\n"
+		      "STMTSYNCR:\t0x%08x\n"
+		      "STMSPER:\t0x%08x\n"
+		      "STMSPTER:\t0x%08x\n"
+		      "STMPRIVMASKR:\t0x%08x\n"
+		      "STMSPSCR:\t0x%08x\n"
+		      "STMSPMSCR:\t0x%08x\n"
+		      "STMFEAT1R:\t0x%08x\n"
+		      "STMFEAT2R:\t0x%08x\n"
+		      "STMFEAT3R:\t0x%08x\n"
+		      "STMDEVID:\t0x%08x\n",
+		      readl_relaxed(drvdata->base + STMTCSR),
+		      readl_relaxed(drvdata->base + STMTSFREQR),
+		      readl_relaxed(drvdata->base + STMSYNCR),
+		      readl_relaxed(drvdata->base + STMSPER),
+		      readl_relaxed(drvdata->base + STMSPTER),
+		      readl_relaxed(drvdata->base + STMPRIVMASKR),
+		      readl_relaxed(drvdata->base + STMSPSCR),
+		      readl_relaxed(drvdata->base + STMSPMSCR),
+		      readl_relaxed(drvdata->base + STMSPFEAT1R),
+		      readl_relaxed(drvdata->base + STMSPFEAT2R),
+		      readl_relaxed(drvdata->base + STMSPFEAT3R),
+		      readl_relaxed(drvdata->base + CORESIGHT_DEVID));
+
+	CS_LOCK(drvdata->base);
+	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	clk_disable_unprepare(drvdata->clk);
+
+	return ret;
+}
+static DEVICE_ATTR_RO(status);
+
+static ssize_t traceid_show(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	unsigned long val;
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	val = drvdata->traceid;
+	return sprintf(buf, "%#lx\n", val);
+}
+
+static ssize_t traceid_store(struct device *dev,
+			     struct device_attribute *attr,
+			     const char *buf, size_t size)
+{
+	int ret;
+	unsigned long val;
+	struct stm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	ret = kstrtoul(buf, 16, &val);
+	if (ret)
+		return ret;
+
+	/* traceid field is 7bit wide on STM32 */
+	drvdata->traceid = val & 0x7f;
+	return size;
+}
+static DEVICE_ATTR_RW(traceid);
+
+static struct attribute *coresight_stm_attrs[] = {
+	&dev_attr_hwevent_enable.attr,
+	&dev_attr_hwevent_select.attr,
+	&dev_attr_port_enable.attr,
+	&dev_attr_port_select.attr,
+	&dev_attr_entities.attr,
+	&dev_attr_status.attr,
+	&dev_attr_traceid.attr,
+	NULL,
+};
+ATTRIBUTE_GROUPS(coresight_stm);
+
+static int stm_get_resource_byname(struct device_node *np,
+				   char *ch_base, struct resource *res)
+{
+	const char *name = NULL;
+	int index = 0, found = 0;
+
+	while (!of_property_read_string_index(np, "reg-names", index, &name)) {
+		if (strcmp(ch_base, name)) {
+			index++;
+			continue;
+		}
+
+		/* We have a match and @index is where it's at */
+		found = 1;
+		break;
+	}
+
+	if (!found)
+		return -EINVAL;
+
+	return of_address_to_resource(np, index, res);
+}
+
+static u32 stm_fundamental_data_size(struct stm_drvdata *drvdata)
+{
+	u32 stmspfeat2r;
+
+	stmspfeat2r = readl_relaxed(drvdata->base + STMSPFEAT2R);
+	return BMVAL(stmspfeat2r, 12, 15);
+}
+
+static u32 stm_num_stimulus_port(struct stm_drvdata *drvdata)
+{
+	u32 numsp;
+
+	numsp = readl_relaxed(drvdata->base + CORESIGHT_DEVID);
+	/*
+	 * NUMPS in STMDEVID is 17 bit long and if equal to 0x0,
+	 * 32 stimulus ports are supported.
+	 */
+	numsp &= 0x1ffff;
+	if (!numsp)
+		numsp = STM_32_CHANNEL;
+	return numsp;
+}
+
+static void stm_init_default_data(struct stm_drvdata *drvdata)
+{
+	/* Don't use port selection */
+	drvdata->stmspscr = 0x0;
+	/*
+	 * Enable all channel regardless of their number.  When port
+	 * selection isn't used (see above) STMSPER applies to all
+	 * 32 channel group available, hence setting all 32 bits to 1
+	 */
+	drvdata->stmsper = ~0x0;
+
+	/*
+	 * Select arbitrary value to start with.  If there is a conflict
+	 * with other tracers the framework will deal with it.
+	 */
+	drvdata->traceid = 0x20;
+
+	bitmap_zero(drvdata->entities, STM_ENTITY_MAX);
+}
+
+static int stm_probe(struct amba_device *adev, const struct amba_id *id)
+{
+	int ret;
+	void __iomem *base;
+	unsigned long *bitmap;
+	struct device *dev = &adev->dev;
+	struct coresight_platform_data *pdata = NULL;
+	struct stm_drvdata *drvdata;
+	struct resource *res = &adev->res;
+	struct resource ch_res;
+	size_t res_size, bitmap_size;
+	struct coresight_desc *desc;
+	struct device_node *np = adev->dev.of_node;
+
+	if (np) {
+		pdata = of_get_coresight_platform_data(dev, np);
+		if (IS_ERR(pdata))
+			return PTR_ERR(pdata);
+		adev->dev.platform_data = pdata;
+	}
+	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata)
+		return -ENOMEM;
+
+	/* Store the driver data pointer for use in exported functions */
+	stmdrvdata = drvdata;
+	drvdata->dev = &adev->dev;
+	dev_set_drvdata(dev, drvdata);
+
+	base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+	drvdata->base = base;
+
+	ret = stm_get_resource_byname(np, "stm-stimulus-base", &ch_res);
+	if (ret)
+		return ret;
+
+	base = devm_ioremap_resource(dev, &ch_res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+	drvdata->chs.base = base;
+
+	ret = clk_prepare_enable(drvdata->clk);
+	if (ret)
+		return ret;
+
+	drvdata->write_64bit = stm_fundamental_data_size(drvdata);
+
+	if (boot_nr_channel) {
+		drvdata->numsp = boot_nr_channel;
+		res_size = min((resource_size_t)(boot_nr_channel *
+				  BYTES_PER_CHANNEL), resource_size(res));
+		bitmap_size = boot_nr_channel * sizeof(long);
+	} else {
+		drvdata->numsp = stm_num_stimulus_port(drvdata);
+		res_size = min((resource_size_t)(drvdata->numsp *
+				 BYTES_PER_CHANNEL), resource_size(res));
+		bitmap_size = drvdata->numsp * sizeof(long);
+	}
+
+	clk_disable_unprepare(drvdata->clk);
+
+	bitmap = devm_kzalloc(dev, bitmap_size, GFP_KERNEL);
+	if (!bitmap)
+		return -ENOMEM;
+	drvdata->chs.bitmap = bitmap;
+
+	spin_lock_init(&drvdata->spinlock);
+
+	drvdata->clk = adev->pclk;
+
+	stm_init_default_data(drvdata);
+
+	desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
+	if (!desc)
+		return -ENOMEM;
+
+	desc->type = CORESIGHT_DEV_TYPE_SOURCE;
+	desc->subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE;
+	desc->ops = &stm_cs_ops;
+	desc->pdata = pdata;
+	desc->dev = dev;
+	desc->groups = coresight_stm_groups;
+	drvdata->csdev = coresight_register(desc);
+	if (IS_ERR(drvdata->csdev))
+		return PTR_ERR(drvdata->csdev);
+
+	drvdata->miscdev.name = pdata->name;
+	drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
+	drvdata->miscdev.fops = &stm_fops;
+	ret = misc_register(&drvdata->miscdev);
+	if (ret)
+		goto err;
+
+	dev_info(drvdata->dev, "STM initialized\n");
+
+	return 0;
+err:
+	coresight_unregister(drvdata->csdev);
+	return ret;
+}
+
+static int stm_remove(struct amba_device *adev)
+{
+	struct stm_drvdata *drvdata = amba_get_drvdata(adev);
+
+	misc_deregister(&drvdata->miscdev);
+	coresight_unregister(drvdata->csdev);
+	return 0;
+}
+
+static struct amba_id stm_ids[] = {
+	{
+		.id     = 0x0003b962,
+		.mask   = 0x0003ffff,
+	},
+	{ 0, 0},
+};
+
+static struct amba_driver stm_driver = {
+	.drv = {
+		.name   = "coresight-stm",
+		.owner	= THIS_MODULE,
+	},
+	.probe          = stm_probe,
+	.remove         = stm_remove,
+	.id_table	= stm_ids,
+};
+
+module_amba_driver(stm_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("CoreSight System Trace Macrocell driver");
diff --git a/include/linux/coresight-stm.h b/include/linux/coresight-stm.h
new file mode 100644
index 000000000000..fc791562ad7c
--- /dev/null
+++ b/include/linux/coresight-stm.h
@@ -0,0 +1,40 @@
+#ifndef __LINUX_CORESIGHT_STM_H_
+#define __LINUX_CORESIGHT_STM_H_
+
+#include <uapi/linux/coresight-stm.h>
+
+/* kernel uses ch_id 0 until a better (more flexible) way is found */
+#define CH_ID_KERNEL	0
+
+#define stm_log_inv(entity_id, ch_id, data, size)		\
+	stm_trace(STM_OPTION_NONE, CH_ID_KERNEL,		\
+	STM_ENTITY_TRACE_KERNEL, data, size)
+
+#define stm_log_inv_ts(entity_id, ch_id, data, size)		\
+	stm_trace(STM_OPTION_TIMESTAMPED, CH_ID_KERNEL,		\
+	STM_ENTITY_TRACE_KERNEL, data, size)			\
+
+#define stm_log_gtd(entity_id, ch_id, data, size)		\
+	stm_trace(STM_OPTION_GUARANTEED, CH_ID_KERNEL,		\
+	STM_ENTITY_TRACE_KERNEL, data, size)			\
+
+#define stm_log_gtd_ts(entity_id, ch_id, data, size)		\
+	stm_trace(STM_OPTION_GUARANTEED |			\
+		  STM_OPTION_TIMESTAMPED,			\
+		  CH_ID_KERNEL, STM_ENTITY_TRACE_KERNEL, data, size)
+
+#define stm_log(entity_id, ch_id, data, size)			\
+	stm_log_inv_ts(entity_id, ch_id, data, size)
+
+#ifdef CONFIG_CORESIGHT_STM
+extern int stm_trace(u32 options, int channel_id,
+		     u8 entity_id, const void *data, u32 size);
+#else
+static inline int stm_trace(u32 options, int channel_id,
+			    u8 entity_id, const void *data, u32 size)
+{
+	return 0;
+}
+#endif
+
+#endif
diff --git a/include/uapi/linux/coresight-stm.h b/include/uapi/linux/coresight-stm.h
new file mode 100644
index 000000000000..208a4d79c4ee
--- /dev/null
+++ b/include/uapi/linux/coresight-stm.h
@@ -0,0 +1,23 @@
+#ifndef __UAPI_CORESIGHT_STM_H_
+#define __UAPI_CORESIGHT_STM_H_
+
+enum {
+	STM_ENTITY_NONE			= 0x00,
+	STM_ENTITY_TRACE_KERNEL		= 0x01,
+	STM_ENTITY_TRACE_USPACE		= 0x10,
+	STM_ENTITY_MAX			= 0xFF,
+};
+
+enum {
+	STM_IOCTL_NONE			= 0x00,
+	STM_IOCTL_SET_OPTIONS		= 0x01,
+	STM_IOCTL_GET_OPTIONS		= 0x10,
+};
+
+enum {
+	STM_OPTION_NONE			= 0x0,
+	STM_OPTION_TIMESTAMPED		= 0x08,
+	STM_OPTION_GUARANTEED		= 0x80,
+};
+
+#endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 5/5] coresight-stm: Bindings for System Trace Macrocell
  2015-02-27 23:04 ` Mathieu Poirier
@ 2015-02-27 23:04   ` Mathieu Poirier
  -1 siblings, 0 replies; 28+ messages in thread
From: Mathieu Poirier @ 2015-02-27 23:04 UTC (permalink / raw)
  To: gregkh; +Cc: linux-arm-kernel, linux-kernel, zhang.chunyan, kaixu.xia

The System Trace Macrocell (STM) is an IP block falling under the
CoreSight umbrella.  It's main purpose it so expose stimulus channels
to any system component for the purpose of information logging.

Bindings for this IP block adds a couple of items to the current
mandatory definition for CoreSight components.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Acked-by: Rob Herring <robh@kernel.org>
---
 .../devicetree/bindings/arm/coresight.txt          | 28 ++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt
index a3089359aaa6..648d50024429 100644
--- a/Documentation/devicetree/bindings/arm/coresight.txt
+++ b/Documentation/devicetree/bindings/arm/coresight.txt
@@ -17,6 +17,7 @@ its hardware characteristcs.
 		- "arm,coresight-tmc", "arm,primecell";
 		- "arm,coresight-funnel", "arm,primecell";
 		- "arm,coresight-etm3x", "arm,primecell";
+		- "arm,coresight-stm", "arm,primecell"; [1]
 
 	* reg: physical base address and length of the register
 	  set(s) of the component.
@@ -31,6 +32,14 @@ its hardware characteristcs.
 	  layout using the generic DT graph presentation found in
 	  "bindings/graph.txt".
 
+* Additional required properties for System Trace Macrocells (STM):
+	* reg: along with the physical base address and length of the register
+	  set as described above, another entry is required to describe the
+	  mapping of the extended stimulus port area.
+
+	* reg-names: the only acceptable values are "stm-base" and
+	  "stm-stimulus-base", each corresponding to the areas defined in "reg".
+
 * Required properties for devices that don't show up on the AMBA bus, such as
   non-configurable replicators:
 
@@ -198,3 +207,22 @@ Example:
 			};
 		};
 	};
+
+4. STM
+	stm@20100000 {
+		compatible = "arm,coresight-stm", "arm,primecell";
+		reg = <0 0x20100000 0 0x1000>,
+		      <0 0x28000000 0 0x180000>;
+		reg-names = "stm-base", "stm-stimulus-base";
+
+		clocks = <&soc_smc50mhz>;
+		clock-names = "apb_pclk";
+		port {
+			stm_out_port: endpoint {
+				remote-endpoint = <&main_funnel_in_port2>;
+			};
+		};
+	};
+
+[1]. There is currently two version of STM: STM32 and STM500.  Both
+have the same HW interface and as such don't need an explicit binding name.
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 5/5] coresight-stm: Bindings for System Trace Macrocell
@ 2015-02-27 23:04   ` Mathieu Poirier
  0 siblings, 0 replies; 28+ messages in thread
From: Mathieu Poirier @ 2015-02-27 23:04 UTC (permalink / raw)
  To: linux-arm-kernel

The System Trace Macrocell (STM) is an IP block falling under the
CoreSight umbrella.  It's main purpose it so expose stimulus channels
to any system component for the purpose of information logging.

Bindings for this IP block adds a couple of items to the current
mandatory definition for CoreSight components.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Acked-by: Rob Herring <robh@kernel.org>
---
 .../devicetree/bindings/arm/coresight.txt          | 28 ++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt
index a3089359aaa6..648d50024429 100644
--- a/Documentation/devicetree/bindings/arm/coresight.txt
+++ b/Documentation/devicetree/bindings/arm/coresight.txt
@@ -17,6 +17,7 @@ its hardware characteristcs.
 		- "arm,coresight-tmc", "arm,primecell";
 		- "arm,coresight-funnel", "arm,primecell";
 		- "arm,coresight-etm3x", "arm,primecell";
+		- "arm,coresight-stm", "arm,primecell"; [1]
 
 	* reg: physical base address and length of the register
 	  set(s) of the component.
@@ -31,6 +32,14 @@ its hardware characteristcs.
 	  layout using the generic DT graph presentation found in
 	  "bindings/graph.txt".
 
+* Additional required properties for System Trace Macrocells (STM):
+	* reg: along with the physical base address and length of the register
+	  set as described above, another entry is required to describe the
+	  mapping of the extended stimulus port area.
+
+	* reg-names: the only acceptable values are "stm-base" and
+	  "stm-stimulus-base", each corresponding to the areas defined in "reg".
+
 * Required properties for devices that don't show up on the AMBA bus, such as
   non-configurable replicators:
 
@@ -198,3 +207,22 @@ Example:
 			};
 		};
 	};
+
+4. STM
+	stm at 20100000 {
+		compatible = "arm,coresight-stm", "arm,primecell";
+		reg = <0 0x20100000 0 0x1000>,
+		      <0 0x28000000 0 0x180000>;
+		reg-names = "stm-base", "stm-stimulus-base";
+
+		clocks = <&soc_smc50mhz>;
+		clock-names = "apb_pclk";
+		port {
+			stm_out_port: endpoint {
+				remote-endpoint = <&main_funnel_in_port2>;
+			};
+		};
+	};
+
+[1]. There is currently two version of STM: STM32 and STM500.  Both
+have the same HW interface and as such don't need an explicit binding name.
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH 4/5] coresight-stm: adding driver for CoreSight STM component
  2015-02-27 23:04   ` Mathieu Poirier
@ 2015-03-07 12:27     ` Alexander Shishkin
  -1 siblings, 0 replies; 28+ messages in thread
From: Alexander Shishkin @ 2015-03-07 12:27 UTC (permalink / raw)
  To: Mathieu Poirier, gregkh
  Cc: linux-arm-kernel, linux-kernel, zhang.chunyan, kaixu.xia

Mathieu Poirier <mathieu.poirier@linaro.org> writes:

> From: Pratik Patel <pratikp@codeaurora.org>
>
> This driver adds support for the STM CoreSight IP block,
> allowing any system compoment (HW or SW) to log and
> aggregate messages via a single entity.
>
> The STM exposes an application defined number of channels
> called stimulus port.  Configuration is done using entries
> in sysfs and channels made available to userspace via devfs.

I somehow missed it when it was posted, but anyway. It looks like we are
solving a very similar problem (the STM device) and I'd like to propose
a generic and architecture independent solution [1]. I also took the
liberty to copy you and Pratik on those patches.

[1] https://lkml.org/lkml/2015/3/7/99

Regards,
--
Alex

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 4/5] coresight-stm: adding driver for CoreSight STM component
@ 2015-03-07 12:27     ` Alexander Shishkin
  0 siblings, 0 replies; 28+ messages in thread
From: Alexander Shishkin @ 2015-03-07 12:27 UTC (permalink / raw)
  To: linux-arm-kernel

Mathieu Poirier <mathieu.poirier@linaro.org> writes:

> From: Pratik Patel <pratikp@codeaurora.org>
>
> This driver adds support for the STM CoreSight IP block,
> allowing any system compoment (HW or SW) to log and
> aggregate messages via a single entity.
>
> The STM exposes an application defined number of channels
> called stimulus port.  Configuration is done using entries
> in sysfs and channels made available to userspace via devfs.

I somehow missed it when it was posted, but anyway. It looks like we are
solving a very similar problem (the STM device) and I'd like to propose
a generic and architecture independent solution [1]. I also took the
liberty to copy you and Pratik on those patches.

[1] https://lkml.org/lkml/2015/3/7/99

Regards,
--
Alex

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 0/5] coresight: next
  2015-02-27 23:04 ` Mathieu Poirier
@ 2015-03-19 22:09   ` Mathieu Poirier
  -1 siblings, 0 replies; 28+ messages in thread
From: Mathieu Poirier @ 2015-03-19 22:09 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-arm-kernel, linux-kernel, Chunyan Zhang, Kaixu Xia

On 27 February 2015 at 16:04, Mathieu Poirier
<mathieu.poirier@linaro.org> wrote:
> These are the latest coresight patches that I'd like you to consider for
> inclusion in your tree.  The set is based on v4.0-rc1.
>
> Thanks,
> Mathieu
>
> Mathieu Poirier (4):
>   coresight: making cpu index lookup arm64 compliant
>   coresight: fixing compilation warnings picked up by 64bit compiler
>   coresight: Adding coresight support for arm64 architecture
>   coresight-stm: Bindings for System Trace Macrocell
>
> Pratik Patel (1):
>   coresight-stm: adding driver for CoreSight STM component
>
>  .../ABI/testing/sysfs-bus-coresight-devices-stm    |   62 ++
>  .../devicetree/bindings/arm/coresight.txt          |   28 +
>  Documentation/trace/coresight.txt                  |   88 +-
>  arch/arm/Kconfig.debug                             |   55 +-
>  arch/arm64/Kconfig.debug                           |    2 +
>  drivers/coresight/Kconfig                          |   71 ++
>  drivers/coresight/Makefile                         |    1 +
>  drivers/coresight/coresight-etb10.c                |    4 +-
>  drivers/coresight/coresight-stm.c                  | 1070 ++++++++++++++++++++
>  drivers/coresight/coresight-tmc.c                  |    4 +-
>  drivers/coresight/of_coresight.c                   |   18 +-
>  include/linux/coresight-stm.h                      |   40 +
>  include/uapi/linux/coresight-stm.h                 |   23 +
>  13 files changed, 1394 insertions(+), 72 deletions(-)
>  create mode 100644 Documentation/ABI/testing/sysfs-bus-coresight-devices-stm
>  create mode 100644 drivers/coresight/Kconfig
>  create mode 100644 drivers/coresight/coresight-stm.c
>  create mode 100644 include/linux/coresight-stm.h
>  create mode 100644 include/uapi/linux/coresight-stm.h
>
> --
> 1.9.1
>

Greg,

I haven't received the usual notifications telling me that you have
added these patches to your tree.  As such I would ask you to
disregard this submission entirely as fair amount of things have
changed since the time it was sent out.  I will send you another set
that has the latest and accurate modifications.

I can also send you a patchset that applies on top of this one and
that brings everything up to date - whichever is the easiest for you.

Best regards,
Mathieu

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 0/5] coresight: next
@ 2015-03-19 22:09   ` Mathieu Poirier
  0 siblings, 0 replies; 28+ messages in thread
From: Mathieu Poirier @ 2015-03-19 22:09 UTC (permalink / raw)
  To: linux-arm-kernel

On 27 February 2015 at 16:04, Mathieu Poirier
<mathieu.poirier@linaro.org> wrote:
> These are the latest coresight patches that I'd like you to consider for
> inclusion in your tree.  The set is based on v4.0-rc1.
>
> Thanks,
> Mathieu
>
> Mathieu Poirier (4):
>   coresight: making cpu index lookup arm64 compliant
>   coresight: fixing compilation warnings picked up by 64bit compiler
>   coresight: Adding coresight support for arm64 architecture
>   coresight-stm: Bindings for System Trace Macrocell
>
> Pratik Patel (1):
>   coresight-stm: adding driver for CoreSight STM component
>
>  .../ABI/testing/sysfs-bus-coresight-devices-stm    |   62 ++
>  .../devicetree/bindings/arm/coresight.txt          |   28 +
>  Documentation/trace/coresight.txt                  |   88 +-
>  arch/arm/Kconfig.debug                             |   55 +-
>  arch/arm64/Kconfig.debug                           |    2 +
>  drivers/coresight/Kconfig                          |   71 ++
>  drivers/coresight/Makefile                         |    1 +
>  drivers/coresight/coresight-etb10.c                |    4 +-
>  drivers/coresight/coresight-stm.c                  | 1070 ++++++++++++++++++++
>  drivers/coresight/coresight-tmc.c                  |    4 +-
>  drivers/coresight/of_coresight.c                   |   18 +-
>  include/linux/coresight-stm.h                      |   40 +
>  include/uapi/linux/coresight-stm.h                 |   23 +
>  13 files changed, 1394 insertions(+), 72 deletions(-)
>  create mode 100644 Documentation/ABI/testing/sysfs-bus-coresight-devices-stm
>  create mode 100644 drivers/coresight/Kconfig
>  create mode 100644 drivers/coresight/coresight-stm.c
>  create mode 100644 include/linux/coresight-stm.h
>  create mode 100644 include/uapi/linux/coresight-stm.h
>
> --
> 1.9.1
>

Greg,

I haven't received the usual notifications telling me that you have
added these patches to your tree.  As such I would ask you to
disregard this submission entirely as fair amount of things have
changed since the time it was sent out.  I will send you another set
that has the latest and accurate modifications.

I can also send you a patchset that applies on top of this one and
that brings everything up to date - whichever is the easiest for you.

Best regards,
Mathieu

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 0/5] coresight: next
  2015-03-19 22:09   ` Mathieu Poirier
@ 2015-03-19 22:24     ` Greg KH
  -1 siblings, 0 replies; 28+ messages in thread
From: Greg KH @ 2015-03-19 22:24 UTC (permalink / raw)
  To: Mathieu Poirier; +Cc: linux-arm-kernel, linux-kernel, Chunyan Zhang, Kaixu Xia

On Thu, Mar 19, 2015 at 04:09:34PM -0600, Mathieu Poirier wrote:
> On 27 February 2015 at 16:04, Mathieu Poirier
> <mathieu.poirier@linaro.org> wrote:
> > These are the latest coresight patches that I'd like you to consider for
> > inclusion in your tree.  The set is based on v4.0-rc1.
> >
> > Thanks,
> > Mathieu
> >
> > Mathieu Poirier (4):
> >   coresight: making cpu index lookup arm64 compliant
> >   coresight: fixing compilation warnings picked up by 64bit compiler
> >   coresight: Adding coresight support for arm64 architecture
> >   coresight-stm: Bindings for System Trace Macrocell
> >
> > Pratik Patel (1):
> >   coresight-stm: adding driver for CoreSight STM component
> >
> >  .../ABI/testing/sysfs-bus-coresight-devices-stm    |   62 ++
> >  .../devicetree/bindings/arm/coresight.txt          |   28 +
> >  Documentation/trace/coresight.txt                  |   88 +-
> >  arch/arm/Kconfig.debug                             |   55 +-
> >  arch/arm64/Kconfig.debug                           |    2 +
> >  drivers/coresight/Kconfig                          |   71 ++
> >  drivers/coresight/Makefile                         |    1 +
> >  drivers/coresight/coresight-etb10.c                |    4 +-
> >  drivers/coresight/coresight-stm.c                  | 1070 ++++++++++++++++++++
> >  drivers/coresight/coresight-tmc.c                  |    4 +-
> >  drivers/coresight/of_coresight.c                   |   18 +-
> >  include/linux/coresight-stm.h                      |   40 +
> >  include/uapi/linux/coresight-stm.h                 |   23 +
> >  13 files changed, 1394 insertions(+), 72 deletions(-)
> >  create mode 100644 Documentation/ABI/testing/sysfs-bus-coresight-devices-stm
> >  create mode 100644 drivers/coresight/Kconfig
> >  create mode 100644 drivers/coresight/coresight-stm.c
> >  create mode 100644 include/linux/coresight-stm.h
> >  create mode 100644 include/uapi/linux/coresight-stm.h
> >
> > --
> > 1.9.1
> >
> 
> Greg,
> 
> I haven't received the usual notifications telling me that you have
> added these patches to your tree.  As such I would ask you to
> disregard this submission entirely as fair amount of things have
> changed since the time it was sent out.  I will send you another set
> that has the latest and accurate modifications.
> 
> I can also send you a patchset that applies on top of this one and
> that brings everything up to date - whichever is the easiest for you.

I'll drop these from my tree and wait for you to send new ones.

Sorry for missing these so far, my patch queue is still huge :(

greg k-h

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 0/5] coresight: next
@ 2015-03-19 22:24     ` Greg KH
  0 siblings, 0 replies; 28+ messages in thread
From: Greg KH @ 2015-03-19 22:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 19, 2015 at 04:09:34PM -0600, Mathieu Poirier wrote:
> On 27 February 2015 at 16:04, Mathieu Poirier
> <mathieu.poirier@linaro.org> wrote:
> > These are the latest coresight patches that I'd like you to consider for
> > inclusion in your tree.  The set is based on v4.0-rc1.
> >
> > Thanks,
> > Mathieu
> >
> > Mathieu Poirier (4):
> >   coresight: making cpu index lookup arm64 compliant
> >   coresight: fixing compilation warnings picked up by 64bit compiler
> >   coresight: Adding coresight support for arm64 architecture
> >   coresight-stm: Bindings for System Trace Macrocell
> >
> > Pratik Patel (1):
> >   coresight-stm: adding driver for CoreSight STM component
> >
> >  .../ABI/testing/sysfs-bus-coresight-devices-stm    |   62 ++
> >  .../devicetree/bindings/arm/coresight.txt          |   28 +
> >  Documentation/trace/coresight.txt                  |   88 +-
> >  arch/arm/Kconfig.debug                             |   55 +-
> >  arch/arm64/Kconfig.debug                           |    2 +
> >  drivers/coresight/Kconfig                          |   71 ++
> >  drivers/coresight/Makefile                         |    1 +
> >  drivers/coresight/coresight-etb10.c                |    4 +-
> >  drivers/coresight/coresight-stm.c                  | 1070 ++++++++++++++++++++
> >  drivers/coresight/coresight-tmc.c                  |    4 +-
> >  drivers/coresight/of_coresight.c                   |   18 +-
> >  include/linux/coresight-stm.h                      |   40 +
> >  include/uapi/linux/coresight-stm.h                 |   23 +
> >  13 files changed, 1394 insertions(+), 72 deletions(-)
> >  create mode 100644 Documentation/ABI/testing/sysfs-bus-coresight-devices-stm
> >  create mode 100644 drivers/coresight/Kconfig
> >  create mode 100644 drivers/coresight/coresight-stm.c
> >  create mode 100644 include/linux/coresight-stm.h
> >  create mode 100644 include/uapi/linux/coresight-stm.h
> >
> > --
> > 1.9.1
> >
> 
> Greg,
> 
> I haven't received the usual notifications telling me that you have
> added these patches to your tree.  As such I would ask you to
> disregard this submission entirely as fair amount of things have
> changed since the time it was sent out.  I will send you another set
> that has the latest and accurate modifications.
> 
> I can also send you a patchset that applies on top of this one and
> that brings everything up to date - whichever is the easiest for you.

I'll drop these from my tree and wait for you to send new ones.

Sorry for missing these so far, my patch queue is still huge :(

greg k-h

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 4/5] coresight-stm: adding driver for CoreSight STM component
  2015-02-27 23:04   ` Mathieu Poirier
@ 2015-03-30 14:04     ` Alexander Shishkin
  -1 siblings, 0 replies; 28+ messages in thread
From: Alexander Shishkin @ 2015-03-30 14:04 UTC (permalink / raw)
  To: Mathieu Poirier, gregkh
  Cc: linux-arm-kernel, linux-kernel, zhang.chunyan, kaixu.xia,
	norbert.schulz, peter.lachner

Mathieu Poirier <mathieu.poirier@linaro.org> writes:

> +static int stm_send(void *addr, const void *data, u32 size)
> +{
> +	u32 len = size;
> +
> +	if (((unsigned long)data & 0x1) && (size >= 1)) {
> +		writeb_relaxed(*(u8 *)data, addr);
> +		data++;
> +		size--;
> +	}
> +	if (((unsigned long)data & 0x2) && (size >= 2)) {
> +		writew_relaxed(*(u16 *)data, addr);
> +		data += 2;
> +		size -= 2;
> +	}
> +
> +	/* now we are 32bit aligned */
> +	while (size >= 4) {
> +		writel_relaxed(*(u32 *)data, addr);
> +		data += 4;
> +		size -= 4;
> +	}
> +
> +	if (size >= 2) {
> +		writew_relaxed(*(u16 *)data, addr);
> +		data += 2;
> +		size -= 2;
> +	}
> +	if (size >= 1) {
> +		writeb_relaxed(*(u8 *)data, addr);
> +		data++;
> +		size--;
> +	}
> +
> +	return len;
> +}
> +
> +static int stm_trace_data(unsigned long ch_addr, u32 options,
> +			  const void *data, u32 size)
> +{
> +	void *addr;
> +
> +	options &= ~STM_OPTION_TIMESTAMPED;
> +	addr = (void *)(ch_addr | stm_channel_off(STM_PKT_TYPE_DATA, options));
> +
> +	return stm_send(addr, data, size);
> +}
> +
> +static inline int stm_trace_hw(u32 options, u32 channel, u8 entity_id,
> +			       const void *data, u32 size)
> +{
> +	int len = 0;
> +	unsigned long ch_addr;
> +	struct stm_drvdata *drvdata = stmdrvdata;
> +
> +
> +	/* get the channel address */
> +	ch_addr = (unsigned long)stm_channel_addr(drvdata, channel);
> +
> +	if (drvdata->write_64bit)
> +		len = stm_trace_data_64bit(ch_addr, options, data, size);
> +	else
> +		/* send the payload data */
> +		len = stm_trace_data(ch_addr, options, data, size);
> +
> +	return len;
> +}

As it looks from the above snippet, you're using a stream of DATA
packets for user's payload. I also noticed that you use an ioctl to
trigger timestamps.

Now, in the STP protocol there are, for example, marked data packets
that can be used to mark beginning of a higher-level message,
timestamped data packets that can be used to mean the same thing and
FLAG packets to mark message boundaries.

In my Intel TH code, I'm using D*TS packet for the beginning of a
message (or "frame") and FLAG packet for the the end of a message.

So my question is, is there any specific STP framing pattern that you
use with Coresight STM or should we perhaps figure out a generic framing
pattern and make it part of the stm class as well?

For example, we can replace stm's .write callback with something like

    int (*packet)(struct stm_data *data,
                  unsigned int type,    /* data, flag, trig etc */
                  unsigned int options, /* timestamped, marked */
                  u64 payload);

and let the stm core do the "framing", which, then, will be common and
consistent across different architectures/stm implementations.

> +static long stm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
> +{
> +	u32 options;
> +	struct stm_node *node = file->private_data;
> +
> +	switch (cmd) {
> +	case STM_IOCTL_SET_OPTIONS:
> +		if (copy_from_user(&options, (void __user *)arg, sizeof(u32)))
> +			return -EFAULT;
> +
> +		options &= (STM_OPTION_TIMESTAMPED | STM_OPTION_GUARANTEED);
> +		node->options = options;
> +		break;
> +	case STM_IOCTL_GET_OPTIONS:
> +		options = node->options;
> +		if (copy_to_user((void __user *)arg, &options, sizeof(options)))
> +			return -EFAULT;
> +		break;
> +	default:
> +		return -EINVAL;
> +	};
> +
> +	return 0;
> +}

That way, we also won't need private ioctl()s, or at least, not for this
reason.

How do you feel about this?

Regards,
--
Alex

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 4/5] coresight-stm: adding driver for CoreSight STM component
@ 2015-03-30 14:04     ` Alexander Shishkin
  0 siblings, 0 replies; 28+ messages in thread
From: Alexander Shishkin @ 2015-03-30 14:04 UTC (permalink / raw)
  To: linux-arm-kernel

Mathieu Poirier <mathieu.poirier@linaro.org> writes:

> +static int stm_send(void *addr, const void *data, u32 size)
> +{
> +	u32 len = size;
> +
> +	if (((unsigned long)data & 0x1) && (size >= 1)) {
> +		writeb_relaxed(*(u8 *)data, addr);
> +		data++;
> +		size--;
> +	}
> +	if (((unsigned long)data & 0x2) && (size >= 2)) {
> +		writew_relaxed(*(u16 *)data, addr);
> +		data += 2;
> +		size -= 2;
> +	}
> +
> +	/* now we are 32bit aligned */
> +	while (size >= 4) {
> +		writel_relaxed(*(u32 *)data, addr);
> +		data += 4;
> +		size -= 4;
> +	}
> +
> +	if (size >= 2) {
> +		writew_relaxed(*(u16 *)data, addr);
> +		data += 2;
> +		size -= 2;
> +	}
> +	if (size >= 1) {
> +		writeb_relaxed(*(u8 *)data, addr);
> +		data++;
> +		size--;
> +	}
> +
> +	return len;
> +}
> +
> +static int stm_trace_data(unsigned long ch_addr, u32 options,
> +			  const void *data, u32 size)
> +{
> +	void *addr;
> +
> +	options &= ~STM_OPTION_TIMESTAMPED;
> +	addr = (void *)(ch_addr | stm_channel_off(STM_PKT_TYPE_DATA, options));
> +
> +	return stm_send(addr, data, size);
> +}
> +
> +static inline int stm_trace_hw(u32 options, u32 channel, u8 entity_id,
> +			       const void *data, u32 size)
> +{
> +	int len = 0;
> +	unsigned long ch_addr;
> +	struct stm_drvdata *drvdata = stmdrvdata;
> +
> +
> +	/* get the channel address */
> +	ch_addr = (unsigned long)stm_channel_addr(drvdata, channel);
> +
> +	if (drvdata->write_64bit)
> +		len = stm_trace_data_64bit(ch_addr, options, data, size);
> +	else
> +		/* send the payload data */
> +		len = stm_trace_data(ch_addr, options, data, size);
> +
> +	return len;
> +}

As it looks from the above snippet, you're using a stream of DATA
packets for user's payload. I also noticed that you use an ioctl to
trigger timestamps.

Now, in the STP protocol there are, for example, marked data packets
that can be used to mark beginning of a higher-level message,
timestamped data packets that can be used to mean the same thing and
FLAG packets to mark message boundaries.

In my Intel TH code, I'm using D*TS packet for the beginning of a
message (or "frame") and FLAG packet for the the end of a message.

So my question is, is there any specific STP framing pattern that you
use with Coresight STM or should we perhaps figure out a generic framing
pattern and make it part of the stm class as well?

For example, we can replace stm's .write callback with something like

    int (*packet)(struct stm_data *data,
                  unsigned int type,    /* data, flag, trig etc */
                  unsigned int options, /* timestamped, marked */
                  u64 payload);

and let the stm core do the "framing", which, then, will be common and
consistent across different architectures/stm implementations.

> +static long stm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
> +{
> +	u32 options;
> +	struct stm_node *node = file->private_data;
> +
> +	switch (cmd) {
> +	case STM_IOCTL_SET_OPTIONS:
> +		if (copy_from_user(&options, (void __user *)arg, sizeof(u32)))
> +			return -EFAULT;
> +
> +		options &= (STM_OPTION_TIMESTAMPED | STM_OPTION_GUARANTEED);
> +		node->options = options;
> +		break;
> +	case STM_IOCTL_GET_OPTIONS:
> +		options = node->options;
> +		if (copy_to_user((void __user *)arg, &options, sizeof(options)))
> +			return -EFAULT;
> +		break;
> +	default:
> +		return -EINVAL;
> +	};
> +
> +	return 0;
> +}

That way, we also won't need private ioctl()s, or at least, not for this
reason.

How do you feel about this?

Regards,
--
Alex

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 4/5] coresight-stm: adding driver for CoreSight STM component
  2015-03-30 14:04     ` Alexander Shishkin
@ 2015-03-30 15:48       ` Mathieu Poirier
  -1 siblings, 0 replies; 28+ messages in thread
From: Mathieu Poirier @ 2015-03-30 15:48 UTC (permalink / raw)
  To: Alexander Shishkin
  Cc: Greg KH, linux-arm-kernel, linux-kernel, Chunyan Zhang,
	Kaixu Xia, norbert.schulz, peter.lachner

On 30 March 2015 at 08:04, Alexander Shishkin
<alexander.shishkin@linux.intel.com> wrote:
> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>
>> +static int stm_send(void *addr, const void *data, u32 size)
>> +{
>> +     u32 len = size;
>> +
>> +     if (((unsigned long)data & 0x1) && (size >= 1)) {
>> +             writeb_relaxed(*(u8 *)data, addr);
>> +             data++;
>> +             size--;
>> +     }
>> +     if (((unsigned long)data & 0x2) && (size >= 2)) {
>> +             writew_relaxed(*(u16 *)data, addr);
>> +             data += 2;
>> +             size -= 2;
>> +     }
>> +
>> +     /* now we are 32bit aligned */
>> +     while (size >= 4) {
>> +             writel_relaxed(*(u32 *)data, addr);
>> +             data += 4;
>> +             size -= 4;
>> +     }
>> +
>> +     if (size >= 2) {
>> +             writew_relaxed(*(u16 *)data, addr);
>> +             data += 2;
>> +             size -= 2;
>> +     }
>> +     if (size >= 1) {
>> +             writeb_relaxed(*(u8 *)data, addr);
>> +             data++;
>> +             size--;
>> +     }
>> +
>> +     return len;
>> +}
>> +
>> +static int stm_trace_data(unsigned long ch_addr, u32 options,
>> +                       const void *data, u32 size)
>> +{
>> +     void *addr;
>> +
>> +     options &= ~STM_OPTION_TIMESTAMPED;
>> +     addr = (void *)(ch_addr | stm_channel_off(STM_PKT_TYPE_DATA, options));
>> +
>> +     return stm_send(addr, data, size);
>> +}
>> +
>> +static inline int stm_trace_hw(u32 options, u32 channel, u8 entity_id,
>> +                            const void *data, u32 size)
>> +{
>> +     int len = 0;
>> +     unsigned long ch_addr;
>> +     struct stm_drvdata *drvdata = stmdrvdata;
>> +
>> +
>> +     /* get the channel address */
>> +     ch_addr = (unsigned long)stm_channel_addr(drvdata, channel);
>> +
>> +     if (drvdata->write_64bit)
>> +             len = stm_trace_data_64bit(ch_addr, options, data, size);
>> +     else
>> +             /* send the payload data */
>> +             len = stm_trace_data(ch_addr, options, data, size);
>> +
>> +     return len;
>> +}
>
> As it looks from the above snippet, you're using a stream of DATA
> packets for user's payload. I also noticed that you use an ioctl to
> trigger timestamps.

Right, the ioctl() conveys user space intentions on that channel.
Options are kept and applied on every packet for as long as the
channel is open.

>
> Now, in the STP protocol there are, for example, marked data packets
> that can be used to mark beginning of a higher-level message,
> timestamped data packets that can be used to mean the same thing and
> FLAG packets to mark message boundaries.

Same on my side, I simply haven't included them yet.  I'll do so in my
next iteration.

>
> In my Intel TH code, I'm using D*TS packet for the beginning of a
> message (or "frame") and FLAG packet for the the end of a message.
>
> So my question is, is there any specific STP framing pattern that you
> use with Coresight STM or should we perhaps figure out a generic framing
> pattern and make it part of the stm class as well?

Now specific pattern... Sending a packet consists of MARK, DATA, FLAG.

>
> For example, we can replace stm's .write callback with something like
>
>     int (*packet)(struct stm_data *data,
>                   unsigned int type,    /* data, flag, trig etc */
>                   unsigned int options, /* timestamped, marked */
>                   u64 payload);
>
> and let the stm core do the "framing", which, then, will be common and
> consistent across different architectures/stm implementations.

I think the framing should be left to individual drivers.  It's only a
matter of time before we get a weird device that doesn't play well
with others, forcing to carry the ugliness in the STM core rather than
the driver.

And isn't carrying "options" redundant?  Using "container_of" on the
"data" field one can get back to the driver specific structure, which
is definitely a better place to keep that information.  I think the
general structure looks good right now, we simply need to find a way
to get rid of the ioctls.

Regarding the same "options", how did you plan on getting those from user space?

>
>> +static long stm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
>> +{
>> +     u32 options;
>> +     struct stm_node *node = file->private_data;
>> +
>> +     switch (cmd) {
>> +     case STM_IOCTL_SET_OPTIONS:
>> +             if (copy_from_user(&options, (void __user *)arg, sizeof(u32)))
>> +                     return -EFAULT;
>> +
>> +             options &= (STM_OPTION_TIMESTAMPED | STM_OPTION_GUARANTEED);
>> +             node->options = options;
>> +             break;
>> +     case STM_IOCTL_GET_OPTIONS:
>> +             options = node->options;
>> +             if (copy_to_user((void __user *)arg, &options, sizeof(options)))
>> +                     return -EFAULT;
>> +             break;
>> +     default:
>> +             return -EINVAL;
>> +     };
>> +
>> +     return 0;
>> +}
>
> That way, we also won't need private ioctl()s, or at least, not for this
> reason.
>
> How do you feel about this?
>
> Regards,
> --
> Alex

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 4/5] coresight-stm: adding driver for CoreSight STM component
@ 2015-03-30 15:48       ` Mathieu Poirier
  0 siblings, 0 replies; 28+ messages in thread
From: Mathieu Poirier @ 2015-03-30 15:48 UTC (permalink / raw)
  To: linux-arm-kernel

On 30 March 2015 at 08:04, Alexander Shishkin
<alexander.shishkin@linux.intel.com> wrote:
> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>
>> +static int stm_send(void *addr, const void *data, u32 size)
>> +{
>> +     u32 len = size;
>> +
>> +     if (((unsigned long)data & 0x1) && (size >= 1)) {
>> +             writeb_relaxed(*(u8 *)data, addr);
>> +             data++;
>> +             size--;
>> +     }
>> +     if (((unsigned long)data & 0x2) && (size >= 2)) {
>> +             writew_relaxed(*(u16 *)data, addr);
>> +             data += 2;
>> +             size -= 2;
>> +     }
>> +
>> +     /* now we are 32bit aligned */
>> +     while (size >= 4) {
>> +             writel_relaxed(*(u32 *)data, addr);
>> +             data += 4;
>> +             size -= 4;
>> +     }
>> +
>> +     if (size >= 2) {
>> +             writew_relaxed(*(u16 *)data, addr);
>> +             data += 2;
>> +             size -= 2;
>> +     }
>> +     if (size >= 1) {
>> +             writeb_relaxed(*(u8 *)data, addr);
>> +             data++;
>> +             size--;
>> +     }
>> +
>> +     return len;
>> +}
>> +
>> +static int stm_trace_data(unsigned long ch_addr, u32 options,
>> +                       const void *data, u32 size)
>> +{
>> +     void *addr;
>> +
>> +     options &= ~STM_OPTION_TIMESTAMPED;
>> +     addr = (void *)(ch_addr | stm_channel_off(STM_PKT_TYPE_DATA, options));
>> +
>> +     return stm_send(addr, data, size);
>> +}
>> +
>> +static inline int stm_trace_hw(u32 options, u32 channel, u8 entity_id,
>> +                            const void *data, u32 size)
>> +{
>> +     int len = 0;
>> +     unsigned long ch_addr;
>> +     struct stm_drvdata *drvdata = stmdrvdata;
>> +
>> +
>> +     /* get the channel address */
>> +     ch_addr = (unsigned long)stm_channel_addr(drvdata, channel);
>> +
>> +     if (drvdata->write_64bit)
>> +             len = stm_trace_data_64bit(ch_addr, options, data, size);
>> +     else
>> +             /* send the payload data */
>> +             len = stm_trace_data(ch_addr, options, data, size);
>> +
>> +     return len;
>> +}
>
> As it looks from the above snippet, you're using a stream of DATA
> packets for user's payload. I also noticed that you use an ioctl to
> trigger timestamps.

Right, the ioctl() conveys user space intentions on that channel.
Options are kept and applied on every packet for as long as the
channel is open.

>
> Now, in the STP protocol there are, for example, marked data packets
> that can be used to mark beginning of a higher-level message,
> timestamped data packets that can be used to mean the same thing and
> FLAG packets to mark message boundaries.

Same on my side, I simply haven't included them yet.  I'll do so in my
next iteration.

>
> In my Intel TH code, I'm using D*TS packet for the beginning of a
> message (or "frame") and FLAG packet for the the end of a message.
>
> So my question is, is there any specific STP framing pattern that you
> use with Coresight STM or should we perhaps figure out a generic framing
> pattern and make it part of the stm class as well?

Now specific pattern... Sending a packet consists of MARK, DATA, FLAG.

>
> For example, we can replace stm's .write callback with something like
>
>     int (*packet)(struct stm_data *data,
>                   unsigned int type,    /* data, flag, trig etc */
>                   unsigned int options, /* timestamped, marked */
>                   u64 payload);
>
> and let the stm core do the "framing", which, then, will be common and
> consistent across different architectures/stm implementations.

I think the framing should be left to individual drivers.  It's only a
matter of time before we get a weird device that doesn't play well
with others, forcing to carry the ugliness in the STM core rather than
the driver.

And isn't carrying "options" redundant?  Using "container_of" on the
"data" field one can get back to the driver specific structure, which
is definitely a better place to keep that information.  I think the
general structure looks good right now, we simply need to find a way
to get rid of the ioctls.

Regarding the same "options", how did you plan on getting those from user space?

>
>> +static long stm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
>> +{
>> +     u32 options;
>> +     struct stm_node *node = file->private_data;
>> +
>> +     switch (cmd) {
>> +     case STM_IOCTL_SET_OPTIONS:
>> +             if (copy_from_user(&options, (void __user *)arg, sizeof(u32)))
>> +                     return -EFAULT;
>> +
>> +             options &= (STM_OPTION_TIMESTAMPED | STM_OPTION_GUARANTEED);
>> +             node->options = options;
>> +             break;
>> +     case STM_IOCTL_GET_OPTIONS:
>> +             options = node->options;
>> +             if (copy_to_user((void __user *)arg, &options, sizeof(options)))
>> +                     return -EFAULT;
>> +             break;
>> +     default:
>> +             return -EINVAL;
>> +     };
>> +
>> +     return 0;
>> +}
>
> That way, we also won't need private ioctl()s, or at least, not for this
> reason.
>
> How do you feel about this?
>
> Regards,
> --
> Alex

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 4/5] coresight-stm: adding driver for CoreSight STM component
  2015-03-30 15:48       ` Mathieu Poirier
@ 2015-03-31 15:04         ` Alexander Shishkin
  -1 siblings, 0 replies; 28+ messages in thread
From: Alexander Shishkin @ 2015-03-31 15:04 UTC (permalink / raw)
  To: Mathieu Poirier
  Cc: Greg KH, linux-arm-kernel, linux-kernel, Chunyan Zhang,
	Kaixu Xia, norbert.schulz, peter.lachner

Mathieu Poirier <mathieu.poirier@linaro.org> writes:

> On 30 March 2015 at 08:04, Alexander Shishkin
> <alexander.shishkin@linux.intel.com> wrote:
>> As it looks from the above snippet, you're using a stream of DATA
>> packets for user's payload. I also noticed that you use an ioctl to
>> trigger timestamps.
>
> Right, the ioctl() conveys user space intentions on that channel.
> Options are kept and applied on every packet for as long as the
> channel is open.

So this means that, for example, if you enable timestamps on a channel,
then every single data packet on that channel will be timestamped, which
is a lot of timestamps. Normally, you would only be interested in the
timestamp on the first data packet in the message (or frame or however
we decide to call it). This is one of the reasons why I'm suggesting a
common framing scheme or a "protocol".

>> Now, in the STP protocol there are, for example, marked data packets
>> that can be used to mark beginning of a higher-level message,
>> timestamped data packets that can be used to mean the same thing and
>> FLAG packets to mark message boundaries.
>
> Same on my side, I simply haven't included them yet.  I'll do so in my
> next iteration.
>
>>
>> In my Intel TH code, I'm using D*TS packet for the beginning of a
>> message (or "frame") and FLAG packet for the the end of a message.
>>
>> So my question is, is there any specific STP framing pattern that you
>> use with Coresight STM or should we perhaps figure out a generic framing
>> pattern and make it part of the stm class as well?
>
> Now specific pattern... Sending a packet consists of MARK, DATA, FLAG.

Is this pattern mandated by a decoder that you use or is there any other
reason why it's exactly that?

>>
>> For example, we can replace stm's .write callback with something like
>>
>>     int (*packet)(struct stm_data *data,
>>                   unsigned int type,    /* data, flag, trig etc */
>>                   unsigned int options, /* timestamped, marked */
>>                   u64 payload);
>>
>> and let the stm core do the "framing", which, then, will be common and
>> consistent across different architectures/stm implementations.
>
> I think the framing should be left to individual drivers.  It's only a
> matter of time before we get a weird device that doesn't play well
> with others, forcing to carry the ugliness in the STM core rather than
> the driver.

Not necessarily. If a device doesn't support one type of packet or the
other, it will be up to them to work around that in the above .packet
callback.

As for the devices that don't play well, there's a question of how much
one can violate the spec and still call oneself compliant.

> And isn't carrying "options" redundant?  Using "container_of" on the
> "data" field one can get back to the driver specific structure, which
> is definitely a better place to keep that information.  I think the
> general structure looks good right now, we simply need to find a way
> to get rid of the ioctls.

No, what I mean by options here is a property of each individual packet,
not the whole channel. For example, if I want the underlying driver to
send a marked data packet, I do

     stm_data->packet(stm_data, STP_PACKET_D8, STP_OPTION_MARKED, payload);

or if I want to send a timestamped flag, I do

     stm_data->packet(stm_data, STP_PACKET_FLAG, STP_OPTION_TS, 0);

Like I said above, there seems little to be gained from enabling
timestamps for all packets in one channel.

> Regarding the same "options", how did you plan on getting those from user space?

Ideally, if we have a framing convension, we don't need to get it from
userspace at all, all userspace should care about is writing data to the
character device and we wrap it up and feed it to the underlying driver.

Regards,
--
Alex

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 4/5] coresight-stm: adding driver for CoreSight STM component
@ 2015-03-31 15:04         ` Alexander Shishkin
  0 siblings, 0 replies; 28+ messages in thread
From: Alexander Shishkin @ 2015-03-31 15:04 UTC (permalink / raw)
  To: linux-arm-kernel

Mathieu Poirier <mathieu.poirier@linaro.org> writes:

> On 30 March 2015 at 08:04, Alexander Shishkin
> <alexander.shishkin@linux.intel.com> wrote:
>> As it looks from the above snippet, you're using a stream of DATA
>> packets for user's payload. I also noticed that you use an ioctl to
>> trigger timestamps.
>
> Right, the ioctl() conveys user space intentions on that channel.
> Options are kept and applied on every packet for as long as the
> channel is open.

So this means that, for example, if you enable timestamps on a channel,
then every single data packet on that channel will be timestamped, which
is a lot of timestamps. Normally, you would only be interested in the
timestamp on the first data packet in the message (or frame or however
we decide to call it). This is one of the reasons why I'm suggesting a
common framing scheme or a "protocol".

>> Now, in the STP protocol there are, for example, marked data packets
>> that can be used to mark beginning of a higher-level message,
>> timestamped data packets that can be used to mean the same thing and
>> FLAG packets to mark message boundaries.
>
> Same on my side, I simply haven't included them yet.  I'll do so in my
> next iteration.
>
>>
>> In my Intel TH code, I'm using D*TS packet for the beginning of a
>> message (or "frame") and FLAG packet for the the end of a message.
>>
>> So my question is, is there any specific STP framing pattern that you
>> use with Coresight STM or should we perhaps figure out a generic framing
>> pattern and make it part of the stm class as well?
>
> Now specific pattern... Sending a packet consists of MARK, DATA, FLAG.

Is this pattern mandated by a decoder that you use or is there any other
reason why it's exactly that?

>>
>> For example, we can replace stm's .write callback with something like
>>
>>     int (*packet)(struct stm_data *data,
>>                   unsigned int type,    /* data, flag, trig etc */
>>                   unsigned int options, /* timestamped, marked */
>>                   u64 payload);
>>
>> and let the stm core do the "framing", which, then, will be common and
>> consistent across different architectures/stm implementations.
>
> I think the framing should be left to individual drivers.  It's only a
> matter of time before we get a weird device that doesn't play well
> with others, forcing to carry the ugliness in the STM core rather than
> the driver.

Not necessarily. If a device doesn't support one type of packet or the
other, it will be up to them to work around that in the above .packet
callback.

As for the devices that don't play well, there's a question of how much
one can violate the spec and still call oneself compliant.

> And isn't carrying "options" redundant?  Using "container_of" on the
> "data" field one can get back to the driver specific structure, which
> is definitely a better place to keep that information.  I think the
> general structure looks good right now, we simply need to find a way
> to get rid of the ioctls.

No, what I mean by options here is a property of each individual packet,
not the whole channel. For example, if I want the underlying driver to
send a marked data packet, I do

     stm_data->packet(stm_data, STP_PACKET_D8, STP_OPTION_MARKED, payload);

or if I want to send a timestamped flag, I do

     stm_data->packet(stm_data, STP_PACKET_FLAG, STP_OPTION_TS, 0);

Like I said above, there seems little to be gained from enabling
timestamps for all packets in one channel.

> Regarding the same "options", how did you plan on getting those from user space?

Ideally, if we have a framing convension, we don't need to get it from
userspace at all, all userspace should care about is writing data to the
character device and we wrap it up and feed it to the underlying driver.

Regards,
--
Alex

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 4/5] coresight-stm: adding driver for CoreSight STM component
  2015-03-31 15:04         ` Alexander Shishkin
@ 2015-04-01 14:27           ` Mathieu Poirier
  -1 siblings, 0 replies; 28+ messages in thread
From: Mathieu Poirier @ 2015-04-01 14:27 UTC (permalink / raw)
  To: Alexander Shishkin
  Cc: Greg KH, linux-arm-kernel, linux-kernel, Chunyan Zhang,
	Kaixu Xia, norbert.schulz, peter.lachner

Adding Al Grant to the conversation - his knowledge on HW tracing for
the ARM architecture is definitely an asset for this kind of planning.
Please add him to future patchset as well.

On 31 March 2015 at 09:04, Alexander Shishkin
<alexander.shishkin@linux.intel.com> wrote:
> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>
>> On 30 March 2015 at 08:04, Alexander Shishkin
>> <alexander.shishkin@linux.intel.com> wrote:
>>> As it looks from the above snippet, you're using a stream of DATA
>>> packets for user's payload. I also noticed that you use an ioctl to
>>> trigger timestamps.
>>
>> Right, the ioctl() conveys user space intentions on that channel.
>> Options are kept and applied on every packet for as long as the
>> channel is open.
>
> So this means that, for example, if you enable timestamps on a channel,
> then every single data packet on that channel will be timestamped, which
> is a lot of timestamps.

That is how the original coresight-stm driver was implemented.  My
initial goal was to upstream something that could be used as a
conversation starter or a foundation to start building on.  I had
planned to look into the protocol specification itself in later steps.
But addressing the issue now is just as worthy.

>Normally, you would only be interested in the
> timestamp on the first data packet in the message (or frame or however
> we decide to call it). This is one of the reasons why I'm suggesting a
> common framing scheme or a "protocol".
>
>>> Now, in the STP protocol there are, for example, marked data packets
>>> that can be used to mark beginning of a higher-level message,
>>> timestamped data packets that can be used to mean the same thing and
>>> FLAG packets to mark message boundaries.
>>
>> Same on my side, I simply haven't included them yet.  I'll do so in my
>> next iteration.
>>
>>>
>>> In my Intel TH code, I'm using D*TS packet for the beginning of a
>>> message (or "frame") and FLAG packet for the the end of a message.

By the way, are you following the OST specification of this is a
scheme you came up with?

>>>
>>> So my question is, is there any specific STP framing pattern that you
>>> use with Coresight STM or should we perhaps figure out a generic framing
>>> pattern and make it part of the stm class as well?
>>
>> Now specific pattern... Sending a packet consists of MARK, DATA, FLAG.
>
> Is this pattern mandated by a decoder that you use or is there any other
> reason why it's exactly that?

The driver was following the OST specification, or something close to
that.  I don't have access to the standard itself and as such not in a
position to assert how accurate the implementation.  That is one of
the reason I left it out of my patchset.

>
>>>
>>> For example, we can replace stm's .write callback with something like
>>>
>>>     int (*packet)(struct stm_data *data,
>>>                   unsigned int type,    /* data, flag, trig etc */
>>>                   unsigned int options, /* timestamped, marked */
>>>                   u64 payload);
>>>
>>> and let the stm core do the "framing", which, then, will be common and
>>> consistent across different architectures/stm implementations.
>>
>> I think the framing should be left to individual drivers.  It's only a
>> matter of time before we get a weird device that doesn't play well
>> with others, forcing to carry the ugliness in the STM core rather than
>> the driver.
>
> Not necessarily. If a device doesn't support one type of packet or the
> other, it will be up to them to work around that in the above .packet
> callback.
>
> As for the devices that don't play well, there's a question of how much
> one can violate the spec and still call oneself compliant.

I understand your point of view.  On my side I'm trying to avoid
painting ourselves in the corner.

>
>> And isn't carrying "options" redundant?  Using "container_of" on the
>> "data" field one can get back to the driver specific structure, which
>> is definitely a better place to keep that information.  I think the
>> general structure looks good right now, we simply need to find a way
>> to get rid of the ioctls.
>
> No, what I mean by options here is a property of each individual packet,
> not the whole channel. For example, if I want the underlying driver to
> send a marked data packet, I do
>
>      stm_data->packet(stm_data, STP_PACKET_D8, STP_OPTION_MARKED, payload);
>
> or if I want to send a timestamped flag, I do
>
>      stm_data->packet(stm_data, STP_PACKET_FLAG, STP_OPTION_TS, 0);

Ah!  It's getting clearer now.

>
> Like I said above, there seems little to be gained from enabling
> timestamps for all packets in one channel.
>
>> Regarding the same "options", how did you plan on getting those from user space?
>
> Ideally, if we have a framing convension, we don't need to get it from
> userspace at all, all userspace should care about is writing data to the
> character device and we wrap it up and feed it to the underlying driver.

What do you have in mind for "framing convention"?  As mentioned above
codeAurora was using the OST specification but Al Grant tell me it
isn't supported anymore.

Thanks for the open dialogue,
Mathieu

>
> Regards,
> --
> Alex

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 4/5] coresight-stm: adding driver for CoreSight STM component
@ 2015-04-01 14:27           ` Mathieu Poirier
  0 siblings, 0 replies; 28+ messages in thread
From: Mathieu Poirier @ 2015-04-01 14:27 UTC (permalink / raw)
  To: linux-arm-kernel

Adding Al Grant to the conversation - his knowledge on HW tracing for
the ARM architecture is definitely an asset for this kind of planning.
Please add him to future patchset as well.

On 31 March 2015 at 09:04, Alexander Shishkin
<alexander.shishkin@linux.intel.com> wrote:
> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>
>> On 30 March 2015 at 08:04, Alexander Shishkin
>> <alexander.shishkin@linux.intel.com> wrote:
>>> As it looks from the above snippet, you're using a stream of DATA
>>> packets for user's payload. I also noticed that you use an ioctl to
>>> trigger timestamps.
>>
>> Right, the ioctl() conveys user space intentions on that channel.
>> Options are kept and applied on every packet for as long as the
>> channel is open.
>
> So this means that, for example, if you enable timestamps on a channel,
> then every single data packet on that channel will be timestamped, which
> is a lot of timestamps.

That is how the original coresight-stm driver was implemented.  My
initial goal was to upstream something that could be used as a
conversation starter or a foundation to start building on.  I had
planned to look into the protocol specification itself in later steps.
But addressing the issue now is just as worthy.

>Normally, you would only be interested in the
> timestamp on the first data packet in the message (or frame or however
> we decide to call it). This is one of the reasons why I'm suggesting a
> common framing scheme or a "protocol".
>
>>> Now, in the STP protocol there are, for example, marked data packets
>>> that can be used to mark beginning of a higher-level message,
>>> timestamped data packets that can be used to mean the same thing and
>>> FLAG packets to mark message boundaries.
>>
>> Same on my side, I simply haven't included them yet.  I'll do so in my
>> next iteration.
>>
>>>
>>> In my Intel TH code, I'm using D*TS packet for the beginning of a
>>> message (or "frame") and FLAG packet for the the end of a message.

By the way, are you following the OST specification of this is a
scheme you came up with?

>>>
>>> So my question is, is there any specific STP framing pattern that you
>>> use with Coresight STM or should we perhaps figure out a generic framing
>>> pattern and make it part of the stm class as well?
>>
>> Now specific pattern... Sending a packet consists of MARK, DATA, FLAG.
>
> Is this pattern mandated by a decoder that you use or is there any other
> reason why it's exactly that?

The driver was following the OST specification, or something close to
that.  I don't have access to the standard itself and as such not in a
position to assert how accurate the implementation.  That is one of
the reason I left it out of my patchset.

>
>>>
>>> For example, we can replace stm's .write callback with something like
>>>
>>>     int (*packet)(struct stm_data *data,
>>>                   unsigned int type,    /* data, flag, trig etc */
>>>                   unsigned int options, /* timestamped, marked */
>>>                   u64 payload);
>>>
>>> and let the stm core do the "framing", which, then, will be common and
>>> consistent across different architectures/stm implementations.
>>
>> I think the framing should be left to individual drivers.  It's only a
>> matter of time before we get a weird device that doesn't play well
>> with others, forcing to carry the ugliness in the STM core rather than
>> the driver.
>
> Not necessarily. If a device doesn't support one type of packet or the
> other, it will be up to them to work around that in the above .packet
> callback.
>
> As for the devices that don't play well, there's a question of how much
> one can violate the spec and still call oneself compliant.

I understand your point of view.  On my side I'm trying to avoid
painting ourselves in the corner.

>
>> And isn't carrying "options" redundant?  Using "container_of" on the
>> "data" field one can get back to the driver specific structure, which
>> is definitely a better place to keep that information.  I think the
>> general structure looks good right now, we simply need to find a way
>> to get rid of the ioctls.
>
> No, what I mean by options here is a property of each individual packet,
> not the whole channel. For example, if I want the underlying driver to
> send a marked data packet, I do
>
>      stm_data->packet(stm_data, STP_PACKET_D8, STP_OPTION_MARKED, payload);
>
> or if I want to send a timestamped flag, I do
>
>      stm_data->packet(stm_data, STP_PACKET_FLAG, STP_OPTION_TS, 0);

Ah!  It's getting clearer now.

>
> Like I said above, there seems little to be gained from enabling
> timestamps for all packets in one channel.
>
>> Regarding the same "options", how did you plan on getting those from user space?
>
> Ideally, if we have a framing convension, we don't need to get it from
> userspace at all, all userspace should care about is writing data to the
> character device and we wrap it up and feed it to the underlying driver.

What do you have in mind for "framing convention"?  As mentioned above
codeAurora was using the OST specification but Al Grant tell me it
isn't supported anymore.

Thanks for the open dialogue,
Mathieu

>
> Regards,
> --
> Alex

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 4/5] coresight-stm: adding driver for CoreSight STM component
  2015-04-01 14:27           ` Mathieu Poirier
@ 2015-04-01 14:28             ` Mathieu Poirier
  -1 siblings, 0 replies; 28+ messages in thread
From: Mathieu Poirier @ 2015-04-01 14:28 UTC (permalink / raw)
  To: Alexander Shishkin
  Cc: Greg KH, linux-arm-kernel, linux-kernel, Chunyan Zhang,
	Kaixu Xia, norbert.schulz, peter.lachner, Al Grant

+ Al Grant

On 1 April 2015 at 08:27, Mathieu Poirier <mathieu.poirier@linaro.org> wrote:
> Adding Al Grant to the conversation - his knowledge on HW tracing for
> the ARM architecture is definitely an asset for this kind of planning.
> Please add him to future patchset as well.
>
> On 31 March 2015 at 09:04, Alexander Shishkin
> <alexander.shishkin@linux.intel.com> wrote:
>> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>>
>>> On 30 March 2015 at 08:04, Alexander Shishkin
>>> <alexander.shishkin@linux.intel.com> wrote:
>>>> As it looks from the above snippet, you're using a stream of DATA
>>>> packets for user's payload. I also noticed that you use an ioctl to
>>>> trigger timestamps.
>>>
>>> Right, the ioctl() conveys user space intentions on that channel.
>>> Options are kept and applied on every packet for as long as the
>>> channel is open.
>>
>> So this means that, for example, if you enable timestamps on a channel,
>> then every single data packet on that channel will be timestamped, which
>> is a lot of timestamps.
>
> That is how the original coresight-stm driver was implemented.  My
> initial goal was to upstream something that could be used as a
> conversation starter or a foundation to start building on.  I had
> planned to look into the protocol specification itself in later steps.
> But addressing the issue now is just as worthy.
>
>>Normally, you would only be interested in the
>> timestamp on the first data packet in the message (or frame or however
>> we decide to call it). This is one of the reasons why I'm suggesting a
>> common framing scheme or a "protocol".
>>
>>>> Now, in the STP protocol there are, for example, marked data packets
>>>> that can be used to mark beginning of a higher-level message,
>>>> timestamped data packets that can be used to mean the same thing and
>>>> FLAG packets to mark message boundaries.
>>>
>>> Same on my side, I simply haven't included them yet.  I'll do so in my
>>> next iteration.
>>>
>>>>
>>>> In my Intel TH code, I'm using D*TS packet for the beginning of a
>>>> message (or "frame") and FLAG packet for the the end of a message.
>
> By the way, are you following the OST specification of this is a
> scheme you came up with?
>
>>>>
>>>> So my question is, is there any specific STP framing pattern that you
>>>> use with Coresight STM or should we perhaps figure out a generic framing
>>>> pattern and make it part of the stm class as well?
>>>
>>> Now specific pattern... Sending a packet consists of MARK, DATA, FLAG.
>>
>> Is this pattern mandated by a decoder that you use or is there any other
>> reason why it's exactly that?
>
> The driver was following the OST specification, or something close to
> that.  I don't have access to the standard itself and as such not in a
> position to assert how accurate the implementation.  That is one of
> the reason I left it out of my patchset.
>
>>
>>>>
>>>> For example, we can replace stm's .write callback with something like
>>>>
>>>>     int (*packet)(struct stm_data *data,
>>>>                   unsigned int type,    /* data, flag, trig etc */
>>>>                   unsigned int options, /* timestamped, marked */
>>>>                   u64 payload);
>>>>
>>>> and let the stm core do the "framing", which, then, will be common and
>>>> consistent across different architectures/stm implementations.
>>>
>>> I think the framing should be left to individual drivers.  It's only a
>>> matter of time before we get a weird device that doesn't play well
>>> with others, forcing to carry the ugliness in the STM core rather than
>>> the driver.
>>
>> Not necessarily. If a device doesn't support one type of packet or the
>> other, it will be up to them to work around that in the above .packet
>> callback.
>>
>> As for the devices that don't play well, there's a question of how much
>> one can violate the spec and still call oneself compliant.
>
> I understand your point of view.  On my side I'm trying to avoid
> painting ourselves in the corner.
>
>>
>>> And isn't carrying "options" redundant?  Using "container_of" on the
>>> "data" field one can get back to the driver specific structure, which
>>> is definitely a better place to keep that information.  I think the
>>> general structure looks good right now, we simply need to find a way
>>> to get rid of the ioctls.
>>
>> No, what I mean by options here is a property of each individual packet,
>> not the whole channel. For example, if I want the underlying driver to
>> send a marked data packet, I do
>>
>>      stm_data->packet(stm_data, STP_PACKET_D8, STP_OPTION_MARKED, payload);
>>
>> or if I want to send a timestamped flag, I do
>>
>>      stm_data->packet(stm_data, STP_PACKET_FLAG, STP_OPTION_TS, 0);
>
> Ah!  It's getting clearer now.
>
>>
>> Like I said above, there seems little to be gained from enabling
>> timestamps for all packets in one channel.
>>
>>> Regarding the same "options", how did you plan on getting those from user space?
>>
>> Ideally, if we have a framing convension, we don't need to get it from
>> userspace at all, all userspace should care about is writing data to the
>> character device and we wrap it up and feed it to the underlying driver.
>
> What do you have in mind for "framing convention"?  As mentioned above
> codeAurora was using the OST specification but Al Grant tell me it
> isn't supported anymore.
>
> Thanks for the open dialogue,
> Mathieu
>
>>
>> Regards,
>> --
>> Alex

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 4/5] coresight-stm: adding driver for CoreSight STM component
@ 2015-04-01 14:28             ` Mathieu Poirier
  0 siblings, 0 replies; 28+ messages in thread
From: Mathieu Poirier @ 2015-04-01 14:28 UTC (permalink / raw)
  To: linux-arm-kernel

+ Al Grant

On 1 April 2015 at 08:27, Mathieu Poirier <mathieu.poirier@linaro.org> wrote:
> Adding Al Grant to the conversation - his knowledge on HW tracing for
> the ARM architecture is definitely an asset for this kind of planning.
> Please add him to future patchset as well.
>
> On 31 March 2015 at 09:04, Alexander Shishkin
> <alexander.shishkin@linux.intel.com> wrote:
>> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>>
>>> On 30 March 2015 at 08:04, Alexander Shishkin
>>> <alexander.shishkin@linux.intel.com> wrote:
>>>> As it looks from the above snippet, you're using a stream of DATA
>>>> packets for user's payload. I also noticed that you use an ioctl to
>>>> trigger timestamps.
>>>
>>> Right, the ioctl() conveys user space intentions on that channel.
>>> Options are kept and applied on every packet for as long as the
>>> channel is open.
>>
>> So this means that, for example, if you enable timestamps on a channel,
>> then every single data packet on that channel will be timestamped, which
>> is a lot of timestamps.
>
> That is how the original coresight-stm driver was implemented.  My
> initial goal was to upstream something that could be used as a
> conversation starter or a foundation to start building on.  I had
> planned to look into the protocol specification itself in later steps.
> But addressing the issue now is just as worthy.
>
>>Normally, you would only be interested in the
>> timestamp on the first data packet in the message (or frame or however
>> we decide to call it). This is one of the reasons why I'm suggesting a
>> common framing scheme or a "protocol".
>>
>>>> Now, in the STP protocol there are, for example, marked data packets
>>>> that can be used to mark beginning of a higher-level message,
>>>> timestamped data packets that can be used to mean the same thing and
>>>> FLAG packets to mark message boundaries.
>>>
>>> Same on my side, I simply haven't included them yet.  I'll do so in my
>>> next iteration.
>>>
>>>>
>>>> In my Intel TH code, I'm using D*TS packet for the beginning of a
>>>> message (or "frame") and FLAG packet for the the end of a message.
>
> By the way, are you following the OST specification of this is a
> scheme you came up with?
>
>>>>
>>>> So my question is, is there any specific STP framing pattern that you
>>>> use with Coresight STM or should we perhaps figure out a generic framing
>>>> pattern and make it part of the stm class as well?
>>>
>>> Now specific pattern... Sending a packet consists of MARK, DATA, FLAG.
>>
>> Is this pattern mandated by a decoder that you use or is there any other
>> reason why it's exactly that?
>
> The driver was following the OST specification, or something close to
> that.  I don't have access to the standard itself and as such not in a
> position to assert how accurate the implementation.  That is one of
> the reason I left it out of my patchset.
>
>>
>>>>
>>>> For example, we can replace stm's .write callback with something like
>>>>
>>>>     int (*packet)(struct stm_data *data,
>>>>                   unsigned int type,    /* data, flag, trig etc */
>>>>                   unsigned int options, /* timestamped, marked */
>>>>                   u64 payload);
>>>>
>>>> and let the stm core do the "framing", which, then, will be common and
>>>> consistent across different architectures/stm implementations.
>>>
>>> I think the framing should be left to individual drivers.  It's only a
>>> matter of time before we get a weird device that doesn't play well
>>> with others, forcing to carry the ugliness in the STM core rather than
>>> the driver.
>>
>> Not necessarily. If a device doesn't support one type of packet or the
>> other, it will be up to them to work around that in the above .packet
>> callback.
>>
>> As for the devices that don't play well, there's a question of how much
>> one can violate the spec and still call oneself compliant.
>
> I understand your point of view.  On my side I'm trying to avoid
> painting ourselves in the corner.
>
>>
>>> And isn't carrying "options" redundant?  Using "container_of" on the
>>> "data" field one can get back to the driver specific structure, which
>>> is definitely a better place to keep that information.  I think the
>>> general structure looks good right now, we simply need to find a way
>>> to get rid of the ioctls.
>>
>> No, what I mean by options here is a property of each individual packet,
>> not the whole channel. For example, if I want the underlying driver to
>> send a marked data packet, I do
>>
>>      stm_data->packet(stm_data, STP_PACKET_D8, STP_OPTION_MARKED, payload);
>>
>> or if I want to send a timestamped flag, I do
>>
>>      stm_data->packet(stm_data, STP_PACKET_FLAG, STP_OPTION_TS, 0);
>
> Ah!  It's getting clearer now.
>
>>
>> Like I said above, there seems little to be gained from enabling
>> timestamps for all packets in one channel.
>>
>>> Regarding the same "options", how did you plan on getting those from user space?
>>
>> Ideally, if we have a framing convension, we don't need to get it from
>> userspace at all, all userspace should care about is writing data to the
>> character device and we wrap it up and feed it to the underlying driver.
>
> What do you have in mind for "framing convention"?  As mentioned above
> codeAurora was using the OST specification but Al Grant tell me it
> isn't supported anymore.
>
> Thanks for the open dialogue,
> Mathieu
>
>>
>> Regards,
>> --
>> Alex

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2015-04-01 14:28 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-27 23:04 [PATCH 0/5] coresight: next Mathieu Poirier
2015-02-27 23:04 ` Mathieu Poirier
2015-02-27 23:04 ` [PATCH 1/5] coresight: making cpu index lookup arm64 compliant Mathieu Poirier
2015-02-27 23:04   ` Mathieu Poirier
2015-02-27 23:04 ` [PATCH 2/5] coresight: fixing compilation warnings picked up by 64bit compiler Mathieu Poirier
2015-02-27 23:04   ` Mathieu Poirier
2015-02-27 23:04 ` [PATCH 3/5] coresight: Adding coresight support for arm64 architecture Mathieu Poirier
2015-02-27 23:04   ` Mathieu Poirier
2015-02-27 23:04 ` [PATCH 4/5] coresight-stm: adding driver for CoreSight STM component Mathieu Poirier
2015-02-27 23:04   ` Mathieu Poirier
2015-03-07 12:27   ` Alexander Shishkin
2015-03-07 12:27     ` Alexander Shishkin
2015-03-30 14:04   ` Alexander Shishkin
2015-03-30 14:04     ` Alexander Shishkin
2015-03-30 15:48     ` Mathieu Poirier
2015-03-30 15:48       ` Mathieu Poirier
2015-03-31 15:04       ` Alexander Shishkin
2015-03-31 15:04         ` Alexander Shishkin
2015-04-01 14:27         ` Mathieu Poirier
2015-04-01 14:27           ` Mathieu Poirier
2015-04-01 14:28           ` Mathieu Poirier
2015-04-01 14:28             ` Mathieu Poirier
2015-02-27 23:04 ` [PATCH 5/5] coresight-stm: Bindings for System Trace Macrocell Mathieu Poirier
2015-02-27 23:04   ` Mathieu Poirier
2015-03-19 22:09 ` [PATCH 0/5] coresight: next Mathieu Poirier
2015-03-19 22:09   ` Mathieu Poirier
2015-03-19 22:24   ` Greg KH
2015-03-19 22:24     ` Greg KH

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.