All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/15][RFC] Android ETM driver changes
@ 2012-06-13  2:01 John Stultz
  2012-06-13  2:01 ` [PATCH 01/15] ARM: etm: Don't require clock control John Stultz
                   ` (9 more replies)
  0 siblings, 10 replies; 16+ messages in thread
From: John Stultz @ 2012-06-13  2:01 UTC (permalink / raw)
  To: LKML
  Cc: John Stultz, Russell King, Paul Gortmaker, Alexander Shishkin,
	Arve Hjønnevåg

The Android kernel tree has a number of changes to the ETM driver.
Arve sent the first 9 of these to the list over a year ago and
got very little response.

I didn't want these to get lost, so I pinged Alexander about
these privately and he stated that he wasn't actively
maintaining the driver, but after skimming the entire set
acked the series and suggested I send it on to Russel for
review and possible inclusion.

So here they are. Please let me know if there are any
objections to merging these, or if further changes are
needed.


CC: Russell King <linux@arm.linux.org.uk>
CC: Paul Gortmaker <paul.gortmaker@windriver.com>
CC: Alexander Shishkin <alexander.shishkin@linux.intel.com>
CC: Arve Hjønnevåg <arve@android.com>

Arve Hjønnevåg (15):
  ARM: etm: Don't require clock control
  ARM: etm: Don't limit tracing to only non-secure code.
  ARM: etm: Don't try to clear the buffer full status after reading the
    buffer
  ARM: etm: Allow range selection
  ARM: etm: Configure data tracing
  ARM: etm: Add some missing locks and error checks
  ARM: etm: Return the entire trace buffer if it is empty after reset
  ARM: etm: Support multiple ETMs/PTMs.
  ARM: etm: Power down etm(s) when tracing is not enabled
  ARM: etm: Wait for etm/ptm(s) to stop before requesting PowerDown
  ARM: etm: Check arch version and disable data tracing for ptm
  ARM: etm: Add sysfs entry to enable timestamps if supported
  ARM: etm: Add sysfs entry to set context-id-size
  ARM: etm: Add sysfs entry to disable branch_output flag
  ARM: etm: Add sysfs entry to enable return stack if supported

 arch/arm/include/asm/hardware/coresight.h |   50 ++-
 arch/arm/kernel/etm.c                     |  680 +++++++++++++++++++++++------
 2 files changed, 587 insertions(+), 143 deletions(-)

-- 
1.7.3.2.146.gca209


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

* [PATCH 01/15] ARM: etm: Don't require clock control
  2012-06-13  2:01 [PATCH 00/15][RFC] Android ETM driver changes John Stultz
@ 2012-06-13  2:01 ` John Stultz
  2012-06-13  8:33   ` Paul Mundt
  2012-06-13  2:01 ` [PATCH 02/15] ARM: etm: Don't limit tracing to only non-secure code John Stultz
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 16+ messages in thread
From: John Stultz @ 2012-06-13  2:01 UTC (permalink / raw)
  To: LKML
  Cc: Arve Hjønnevåg, Russell King, Paul Gortmaker,
	Alexander Shishkin, Mathieu Poirier, John Stultz

From: Arve Hjønnevåg <arve@android.com>

If clk_get fail, assume the etb does not need a separate clock.

CC: Russell King <linux@arm.linux.org.uk>
CC: Paul Gortmaker <paul.gortmaker@windriver.com>
CC: Alexander Shishkin <alexander.shishkin@linux.intel.com>
CC: Mathieu Poirier <mathieu.poirier@linaro.org>

Acked-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: Arve Hjønnevåg <arve@android.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 arch/arm/kernel/etm.c |   15 ++++++++-------
 1 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index 36d20bd..bd295e8 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -362,13 +362,12 @@ static int __devinit etb_probe(struct amba_device *dev, const struct amba_id *id
 	if (ret)
 		goto out_unmap;
 
+	/* Get optional clock. Currently used to select clock source on omap3 */
 	t->emu_clk = clk_get(&dev->dev, "emu_src_ck");
-	if (IS_ERR(t->emu_clk)) {
+	if (IS_ERR(t->emu_clk))
 		dev_dbg(&dev->dev, "Failed to obtain emu_src_ck.\n");
-		return -EFAULT;
-	}
-
-	clk_enable(t->emu_clk);
+	else
+		clk_enable(t->emu_clk);
 
 	etb_unlock(t);
 	t->etb_bufsz = etb_readl(t, ETBR_DEPTH);
@@ -403,8 +402,10 @@ static int etb_remove(struct amba_device *dev)
 	iounmap(t->etb_regs);
 	t->etb_regs = NULL;
 
-	clk_disable(t->emu_clk);
-	clk_put(t->emu_clk);
+	if (!IS_ERR(t->emu_clk)) {
+		clk_disable(t->emu_clk);
+		clk_put(t->emu_clk);
+	}
 
 	amba_release_regions(dev);
 
-- 
1.7.3.2.146.gca209


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

* [PATCH 02/15] ARM: etm: Don't limit tracing to only non-secure code.
  2012-06-13  2:01 [PATCH 00/15][RFC] Android ETM driver changes John Stultz
  2012-06-13  2:01 ` [PATCH 01/15] ARM: etm: Don't require clock control John Stultz
@ 2012-06-13  2:01 ` John Stultz
  2012-06-13  2:01 ` [PATCH 03/15] ARM: etm: Don't try to clear the buffer full status after reading the buffer John Stultz
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: John Stultz @ 2012-06-13  2:01 UTC (permalink / raw)
  To: LKML
  Cc: Arve Hjønnevåg, Russell King, Paul Gortmaker,
	Alexander Shishkin, Mathieu Poirier, John Stultz

From: Arve Hjønnevåg <arve@android.com>

On some systems kernel code is considered secure, and this code
already limits tracing to the kernel text segment which results
in no trace data.

CC: Russell King <linux@arm.linux.org.uk>
CC: Paul Gortmaker <paul.gortmaker@windriver.com>
CC: Alexander Shishkin <alexander.shishkin@linux.intel.com>
CC: Mathieu Poirier <mathieu.poirier@linaro.org>

Acked-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: Arve Hjønnevåg <arve@android.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 arch/arm/kernel/etm.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index bd295e8..d7622f9 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -56,7 +56,7 @@ static inline bool trace_isrunning(struct tracectx *t)
 static int etm_setup_address_range(struct tracectx *t, int n,
 		unsigned long start, unsigned long end, int exclude, int data)
 {
-	u32 flags = ETMAAT_ARM | ETMAAT_IGNCONTEXTID | ETMAAT_NSONLY | \
+	u32 flags = ETMAAT_ARM | ETMAAT_IGNCONTEXTID | ETMAAT_IGNSECURITY |
 		    ETMAAT_NOVALCMP;
 
 	if (n < 1 || n > t->ncmppairs)
-- 
1.7.3.2.146.gca209


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

* [PATCH 03/15] ARM: etm: Don't try to clear the buffer full status after reading the buffer
  2012-06-13  2:01 [PATCH 00/15][RFC] Android ETM driver changes John Stultz
  2012-06-13  2:01 ` [PATCH 01/15] ARM: etm: Don't require clock control John Stultz
  2012-06-13  2:01 ` [PATCH 02/15] ARM: etm: Don't limit tracing to only non-secure code John Stultz
@ 2012-06-13  2:01 ` John Stultz
  2012-06-13  2:01 ` [PATCH 04/15] ARM: etm: Allow range selection John Stultz
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: John Stultz @ 2012-06-13  2:01 UTC (permalink / raw)
  To: LKML
  Cc: Arve Hjønnevåg, Russell King, Paul Gortmaker,
	Alexander Shishkin, Mathieu Poirier, John Stultz

From: Arve Hjønnevåg <arve@android.com>

If the write address was at the end of the buffer, toggling the trace
capture bit would set the RAM-full status instead of clearing it, and
if any of the stop bits in the formatter is set toggling the trace
capture bit may not do anything.

Instead use the read position to find out if the data has already
been returned.

This also fixes the read function so it works when the trace buffer is
larger than the buffer passed in from user space. The old version
would reset the trace buffer pointers after every read, so the second
call to read would always return 0.

CC: Russell King <linux@arm.linux.org.uk>
CC: Paul Gortmaker <paul.gortmaker@windriver.com>
CC: Alexander Shishkin <alexander.shishkin@linux.intel.com>
CC: Mathieu Poirier <mathieu.poirier@linaro.org>

Acked-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: Arve Hjønnevåg <arve@android.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 arch/arm/kernel/etm.c |   58 ++++++++++++++++++++++---------------------------
 1 files changed, 26 insertions(+), 32 deletions(-)

diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index d7622f9..a51bccc 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -92,6 +92,7 @@ static int trace_start(struct tracectx *t)
 
 	etb_unlock(t);
 
+	etb_writel(t, 0, ETBR_WRITEADDR);
 	etb_writel(t, 0, ETBR_FORMATTERCTRL);
 	etb_writel(t, 1, ETBR_CTRL);
 
@@ -185,24 +186,15 @@ static int trace_stop(struct tracectx *t)
 static int etb_getdatalen(struct tracectx *t)
 {
 	u32 v;
-	int rp, wp;
+	int wp;
 
 	v = etb_readl(t, ETBR_STATUS);
 
 	if (v & 1)
 		return t->etb_bufsz;
 
-	rp = etb_readl(t, ETBR_READADDR);
 	wp = etb_readl(t, ETBR_WRITEADDR);
-
-	if (rp > wp) {
-		etb_writel(t, 0, ETBR_READADDR);
-		etb_writel(t, 0, ETBR_WRITEADDR);
-
-		return 0;
-	}
-
-	return wp - rp;
+	return wp;
 }
 
 /* sysrq+v will always stop the running trace and leave it at that */
@@ -235,14 +227,6 @@ static void etm_dump(void)
 		printk("%08x", cpu_to_be32(etb_readl(t, ETBR_READMEM)));
 	printk(KERN_INFO "\n--- ETB buffer end ---\n");
 
-	/* deassert the overflow bit */
-	etb_writel(t, 1, ETBR_CTRL);
-	etb_writel(t, 0, ETBR_CTRL);
-
-	etb_writel(t, 0, ETBR_TRIGGERCOUNT);
-	etb_writel(t, 0, ETBR_READADDR);
-	etb_writel(t, 0, ETBR_WRITEADDR);
-
 	etb_lock(t);
 }
 
@@ -276,6 +260,10 @@ static ssize_t etb_read(struct file *file, char __user *data,
 	struct tracectx *t = file->private_data;
 	u32 first = 0;
 	u32 *buf;
+	int wpos;
+	int skip;
+	long wlength;
+	loff_t pos = *ppos;
 
 	mutex_lock(&t->mutex);
 
@@ -290,28 +278,34 @@ static ssize_t etb_read(struct file *file, char __user *data,
 	if (total == t->etb_bufsz)
 		first = etb_readl(t, ETBR_WRITEADDR);
 
+	if (pos > total * 4) {
+		skip = 0;
+		wpos = total;
+	} else {
+		skip = (int)pos % 4;
+		wpos = (int)pos / 4;
+	}
+	total -= wpos;
+	first = (first + wpos) % t->etb_bufsz;
+
 	etb_writel(t, first, ETBR_READADDR);
 
-	length = min(total * 4, (int)len);
-	buf = vmalloc(length);
+	wlength = min(total, DIV_ROUND_UP(skip + (int)len, 4));
+	length = min(total * 4 - skip, (int)len);
+	buf = vmalloc(wlength * 4);
 
-	dev_dbg(t->dev, "ETB buffer length: %d\n", total);
+	dev_dbg(t->dev, "ETB read %ld bytes to %lld from %ld words at %d\n",
+		length, pos, wlength, first);
+	dev_dbg(t->dev, "ETB buffer length: %d\n", total + wpos);
 	dev_dbg(t->dev, "ETB status reg: %x\n", etb_readl(t, ETBR_STATUS));
-	for (i = 0; i < length / 4; i++)
+	for (i = 0; i < wlength; i++)
 		buf[i] = etb_readl(t, ETBR_READMEM);
 
-	/* the only way to deassert overflow bit in ETB status is this */
-	etb_writel(t, 1, ETBR_CTRL);
-	etb_writel(t, 0, ETBR_CTRL);
-
-	etb_writel(t, 0, ETBR_WRITEADDR);
-	etb_writel(t, 0, ETBR_READADDR);
-	etb_writel(t, 0, ETBR_TRIGGERCOUNT);
-
 	etb_lock(t);
 
-	length -= copy_to_user(data, buf, length);
+	length -= copy_to_user(data, (u8 *)buf + skip, length);
 	vfree(buf);
+	*ppos = pos + length;
 
 out:
 	mutex_unlock(&t->mutex);
-- 
1.7.3.2.146.gca209


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

* [PATCH 04/15] ARM: etm: Allow range selection
  2012-06-13  2:01 [PATCH 00/15][RFC] Android ETM driver changes John Stultz
                   ` (2 preceding siblings ...)
  2012-06-13  2:01 ` [PATCH 03/15] ARM: etm: Don't try to clear the buffer full status after reading the buffer John Stultz
@ 2012-06-13  2:01 ` John Stultz
  2012-06-13  2:01 ` [PATCH 05/15] ARM: etm: Configure data tracing John Stultz
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: John Stultz @ 2012-06-13  2:01 UTC (permalink / raw)
  To: LKML
  Cc: Arve Hjønnevåg, Russell King, Paul Gortmaker,
	Alexander Shishkin, Mathieu Poirier, John Stultz

From: Arve Hjønnevåg <arve@android.com>

Trace kernel text segment by default as before, allow tracing of other
ranges by writing a range to /sys/devices/etm/trace_range, or to trace
everything by writing 0 0.

CC: Russell King <linux@arm.linux.org.uk>
CC: Paul Gortmaker <paul.gortmaker@windriver.com>
CC: Alexander Shishkin <alexander.shishkin@linux.intel.com>
CC: Mathieu Poirier <mathieu.poirier@linaro.org>

Acked-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: Arve Hjønnevåg <arve@android.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 arch/arm/kernel/etm.c |   49 ++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index a51bccc..bf34d34 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -41,12 +41,17 @@ struct tracectx {
 	unsigned long	flags;
 	int		ncmppairs;
 	int		etm_portsz;
+	unsigned long	range_start;
+	unsigned long	range_end;
 	struct device	*dev;
 	struct clk	*emu_clk;
 	struct mutex	mutex;
 };
 
-static struct tracectx tracer;
+static struct tracectx tracer = {
+	.range_start = (unsigned long)_stext,
+	.range_end = (unsigned long)_etext,
+};
 
 static inline bool trace_isrunning(struct tracectx *t)
 {
@@ -116,8 +121,12 @@ static int trace_start(struct tracectx *t)
 		return -EFAULT;
 	}
 
-	etm_setup_address_range(t, 1, (unsigned long)_stext,
-			(unsigned long)_etext, 0, 0);
+	if (t->range_start || t->range_end)
+		etm_setup_address_range(t, 1,
+					t->range_start, t->range_end, 0, 0);
+	else
+		etm_writel(t, ETMTE_INCLEXCL, ETMR_TRACEENCTRL);
+
 	etm_writel(t, 0, ETMR_TRACEENCTRL2);
 	etm_writel(t, 0, ETMR_TRACESSCTRL);
 	etm_writel(t, 0x6f, ETMR_TRACEENEVT);
@@ -526,6 +535,35 @@ static ssize_t trace_mode_store(struct kobject *kobj,
 static struct kobj_attribute trace_mode_attr =
 	__ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store);
 
+static ssize_t trace_range_show(struct kobject *kobj,
+				  struct kobj_attribute *attr,
+				  char *buf)
+{
+	return sprintf(buf, "%08lx %08lx\n",
+			tracer.range_start, tracer.range_end);
+}
+
+static ssize_t trace_range_store(struct kobject *kobj,
+				   struct kobj_attribute *attr,
+				   const char *buf, size_t n)
+{
+	unsigned long range_start, range_end;
+
+	if (sscanf(buf, "%lx %lx", &range_start, &range_end) != 2)
+		return -EINVAL;
+
+	mutex_lock(&tracer.mutex);
+	tracer.range_start = range_start;
+	tracer.range_end = range_end;
+	mutex_unlock(&tracer.mutex);
+
+	return n;
+}
+
+
+static struct kobj_attribute trace_range_attr =
+	__ATTR(trace_range, 0644, trace_range_show, trace_range_store);
+
 static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id)
 {
 	struct tracectx *t = &tracer;
@@ -577,6 +615,10 @@ static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id
 	if (ret)
 		dev_dbg(&dev->dev, "Failed to create trace_mode in sysfs\n");
 
+	ret = sysfs_create_file(&dev->dev.kobj, &trace_range_attr.attr);
+	if (ret)
+		dev_dbg(&dev->dev, "Failed to create trace_range in sysfs\n");
+
 	dev_dbg(t->dev, "ETM AMBA driver initialized.\n");
 
 out:
@@ -606,6 +648,7 @@ static int etm_remove(struct amba_device *dev)
 	sysfs_remove_file(&dev->dev.kobj, &trace_running_attr.attr);
 	sysfs_remove_file(&dev->dev.kobj, &trace_info_attr.attr);
 	sysfs_remove_file(&dev->dev.kobj, &trace_mode_attr.attr);
+	sysfs_remove_file(&dev->dev.kobj, &trace_range_attr.attr);
 
 	return 0;
 }
-- 
1.7.3.2.146.gca209


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

* [PATCH 05/15] ARM: etm: Configure data tracing
  2012-06-13  2:01 [PATCH 00/15][RFC] Android ETM driver changes John Stultz
                   ` (3 preceding siblings ...)
  2012-06-13  2:01 ` [PATCH 04/15] ARM: etm: Allow range selection John Stultz
@ 2012-06-13  2:01 ` John Stultz
  2012-06-13  2:01 ` [PATCH 06/15] ARM: etm: Add some missing locks and error checks John Stultz
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: John Stultz @ 2012-06-13  2:01 UTC (permalink / raw)
  To: LKML
  Cc: Arve Hjønnevåg, Russell King, Paul Gortmaker,
	Alexander Shishkin, Mathieu Poirier, John Stultz

From: Arve Hjønnevåg <arve@android.com>

The old code enabled data tracing, but did not configure the
range. We now configure it to trace all data addresses by default,
and add a trace_data_range attribute to change the range or disable
data tracing.

CC: Russell King <linux@arm.linux.org.uk>
CC: Paul Gortmaker <paul.gortmaker@windriver.com>
CC: Alexander Shishkin <alexander.shishkin@linux.intel.com>
CC: Mathieu Poirier <mathieu.poirier@linaro.org>

Acked-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: Arve Hjønnevåg <arve@android.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 arch/arm/include/asm/hardware/coresight.h |   10 +++-
 arch/arm/kernel/etm.c                     |   77 +++++++++++++++++++++++++++-
 2 files changed, 83 insertions(+), 4 deletions(-)

diff --git a/arch/arm/include/asm/hardware/coresight.h b/arch/arm/include/asm/hardware/coresight.h
index 7ecd793..6ea507f 100644
--- a/arch/arm/include/asm/hardware/coresight.h
+++ b/arch/arm/include/asm/hardware/coresight.h
@@ -17,9 +17,11 @@
 #define TRACER_ACCESSED_BIT	0
 #define TRACER_RUNNING_BIT	1
 #define TRACER_CYCLE_ACC_BIT	2
+#define TRACER_TRACE_DATA_BIT	3
 #define TRACER_ACCESSED		BIT(TRACER_ACCESSED_BIT)
 #define TRACER_RUNNING		BIT(TRACER_RUNNING_BIT)
 #define TRACER_CYCLE_ACC	BIT(TRACER_CYCLE_ACC_BIT)
+#define TRACER_TRACE_DATA	BIT(TRACER_TRACE_DATA_BIT)
 
 #define TRACER_TIMEOUT 10000
 
@@ -113,8 +115,14 @@
 #define ETMR_TRACEENCTRL	0x24
 #define ETMTE_INCLEXCL		BIT(24)
 #define ETMR_TRACEENEVT		0x20
+
+#define ETMR_VIEWDATAEVT	0x30
+#define ETMR_VIEWDATACTRL1	0x34
+#define ETMR_VIEWDATACTRL2	0x38
+#define ETMR_VIEWDATACTRL3	0x3c
+#define ETMVDC3_EXCLONLY	BIT(16)
+
 #define ETMCTRL_OPTS		(ETMCTRL_DO_CPRT | \
-				ETMCTRL_DATA_DO_ADDR | \
 				ETMCTRL_BRANCH_OUTPUT | \
 				ETMCTRL_DO_CONTEXTID)
 
diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index bf34d34..c651cf9 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -43,6 +43,8 @@ struct tracectx {
 	int		etm_portsz;
 	unsigned long	range_start;
 	unsigned long	range_end;
+	unsigned long	data_range_start;
+	unsigned long	data_range_end;
 	struct device	*dev;
 	struct clk	*emu_clk;
 	struct mutex	mutex;
@@ -84,8 +86,15 @@ static int etm_setup_address_range(struct tracectx *t, int n,
 	etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2 + 1));
 	etm_writel(t, end, ETMR_COMP_VAL(n * 2 + 1));
 
-	flags = exclude ? ETMTE_INCLEXCL : 0;
-	etm_writel(t, flags | (1 << n), ETMR_TRACEENCTRL);
+	if (data) {
+		flags = exclude ? ETMVDC3_EXCLONLY : 0;
+		if (exclude)
+			n += 8;
+		etm_writel(t, flags | BIT(n), ETMR_VIEWDATACTRL3);
+	} else {
+		flags = exclude ? ETMTE_INCLEXCL : 0;
+		etm_writel(t, flags | (1 << n), ETMR_TRACEENCTRL);
+	}
 
 	return 0;
 }
@@ -109,6 +118,9 @@ static int trace_start(struct tracectx *t)
 	if (t->flags & TRACER_CYCLE_ACC)
 		v |= ETMCTRL_CYCLEACCURATE;
 
+	if (t->flags & TRACER_TRACE_DATA)
+		v |= ETMCTRL_DATA_DO_ADDR;
+
 	etm_unlock(t);
 
 	etm_writel(t, v, ETMR_CTRL);
@@ -131,6 +143,17 @@ static int trace_start(struct tracectx *t)
 	etm_writel(t, 0, ETMR_TRACESSCTRL);
 	etm_writel(t, 0x6f, ETMR_TRACEENEVT);
 
+	etm_writel(t, 0, ETMR_VIEWDATACTRL1);
+	etm_writel(t, 0, ETMR_VIEWDATACTRL2);
+
+	if (t->data_range_start || t->data_range_end)
+		etm_setup_address_range(t, 2, t->data_range_start,
+					t->data_range_end, 0, 1);
+	else
+		etm_writel(t, ETMVDC3_EXCLONLY, ETMR_VIEWDATACTRL3);
+
+	etm_writel(t, 0x6f, ETMR_VIEWDATAEVT);
+
 	v &= ~ETMCTRL_PROGRAM;
 	v |= ETMCTRL_PORTSEL;
 
@@ -564,6 +587,48 @@ static ssize_t trace_range_store(struct kobject *kobj,
 static struct kobj_attribute trace_range_attr =
 	__ATTR(trace_range, 0644, trace_range_show, trace_range_store);
 
+static ssize_t trace_data_range_show(struct kobject *kobj,
+				  struct kobj_attribute *attr,
+				  char *buf)
+{
+	unsigned long range_start;
+	u64 range_end;
+	mutex_lock(&tracer.mutex);
+	range_start = tracer.data_range_start;
+	range_end = tracer.data_range_end;
+	if (!range_end && (tracer.flags & TRACER_TRACE_DATA))
+		range_end = 0x100000000ULL;
+	mutex_unlock(&tracer.mutex);
+	return sprintf(buf, "%08lx %08llx\n", range_start, range_end);
+}
+
+static ssize_t trace_data_range_store(struct kobject *kobj,
+				   struct kobj_attribute *attr,
+				   const char *buf, size_t n)
+{
+	unsigned long range_start;
+	u64 range_end;
+
+	if (sscanf(buf, "%lx %llx", &range_start, &range_end) != 2)
+		return -EINVAL;
+
+	mutex_lock(&tracer.mutex);
+	tracer.data_range_start = range_start;
+	tracer.data_range_end = (unsigned long)range_end;
+	if (range_end)
+		tracer.flags |= TRACER_TRACE_DATA;
+	else
+		tracer.flags &= ~TRACER_TRACE_DATA;
+	mutex_unlock(&tracer.mutex);
+
+	return n;
+}
+
+
+static struct kobj_attribute trace_data_range_attr =
+	__ATTR(trace_data_range, 0644,
+		trace_data_range_show, trace_data_range_store);
+
 static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id)
 {
 	struct tracectx *t = &tracer;
@@ -589,7 +654,7 @@ static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id
 
 	mutex_init(&t->mutex);
 	t->dev = &dev->dev;
-	t->flags = TRACER_CYCLE_ACC;
+	t->flags = TRACER_CYCLE_ACC | TRACER_TRACE_DATA;
 	t->etm_portsz = 1;
 
 	etm_unlock(t);
@@ -619,6 +684,11 @@ static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id
 	if (ret)
 		dev_dbg(&dev->dev, "Failed to create trace_range in sysfs\n");
 
+	ret = sysfs_create_file(&dev->dev.kobj, &trace_data_range_attr.attr);
+	if (ret)
+		dev_dbg(&dev->dev,
+			"Failed to create trace_data_range in sysfs\n");
+
 	dev_dbg(t->dev, "ETM AMBA driver initialized.\n");
 
 out:
@@ -649,6 +719,7 @@ static int etm_remove(struct amba_device *dev)
 	sysfs_remove_file(&dev->dev.kobj, &trace_info_attr.attr);
 	sysfs_remove_file(&dev->dev.kobj, &trace_mode_attr.attr);
 	sysfs_remove_file(&dev->dev.kobj, &trace_range_attr.attr);
+	sysfs_remove_file(&dev->dev.kobj, &trace_data_range_attr.attr);
 
 	return 0;
 }
-- 
1.7.3.2.146.gca209


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

* [PATCH 06/15] ARM: etm: Add some missing locks and error checks
  2012-06-13  2:01 [PATCH 00/15][RFC] Android ETM driver changes John Stultz
                   ` (4 preceding siblings ...)
  2012-06-13  2:01 ` [PATCH 05/15] ARM: etm: Configure data tracing John Stultz
@ 2012-06-13  2:01 ` John Stultz
  2012-06-13  2:01 ` [PATCH 07/15] ARM: etm: Return the entire trace buffer if it is empty after reset John Stultz
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: John Stultz @ 2012-06-13  2:01 UTC (permalink / raw)
  To: LKML
  Cc: Arve Hjønnevåg, Russell King, Paul Gortmaker,
	Alexander Shishkin, Mathieu Poirier, John Stultz

From: Arve Hjønnevåg <arve@android.com>

It is not safe to call etm_lock or etb_lock without holding the
mutex since another thread may also have unlocked the registers.

Also add some missing checks for valid etb_regs in the etm sysfs
entries.

CC: Russell King <linux@arm.linux.org.uk>
CC: Paul Gortmaker <paul.gortmaker@windriver.com>
CC: Alexander Shishkin <alexander.shishkin@linux.intel.com>
CC: Mathieu Poirier <mathieu.poirier@linaro.org>

Acked-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: Arve Hjønnevåg <arve@android.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 arch/arm/kernel/etm.c |   57 +++++++++++++++++++++++++++++++++---------------
 1 files changed, 39 insertions(+), 18 deletions(-)

diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index c651cf9..3d21cf6 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -264,8 +264,13 @@ static void etm_dump(void)
 
 static void sysrq_etm_dump(int key)
 {
+	if (!mutex_trylock(&tracer.mutex)) {
+		printk(KERN_INFO "Tracing hardware busy\n");
+		return;
+	}
 	dev_dbg(tracer.dev, "Dumping ETB buffer\n");
 	etm_dump();
+	mutex_unlock(&tracer.mutex);
 }
 
 static struct sysrq_key_op sysrq_etm_op = {
@@ -374,6 +379,7 @@ static int __devinit etb_probe(struct amba_device *dev, const struct amba_id *id
 	if (ret)
 		goto out;
 
+	mutex_lock(&t->mutex);
 	t->etb_regs = ioremap_nocache(dev->res.start, resource_size(&dev->res));
 	if (!t->etb_regs) {
 		ret = -ENOMEM;
@@ -382,6 +388,16 @@ static int __devinit etb_probe(struct amba_device *dev, const struct amba_id *id
 
 	amba_set_drvdata(dev, t);
 
+	etb_unlock(t);
+	t->etb_bufsz = etb_readl(t, ETBR_DEPTH);
+	dev_dbg(&dev->dev, "Size: %x\n", t->etb_bufsz);
+
+	/* make sure trace capture is disabled */
+	etb_writel(t, 0, ETBR_CTRL);
+	etb_writel(t, 0x1000, ETBR_FORMATTERCTRL);
+	etb_lock(t);
+	mutex_unlock(&t->mutex);
+
 	etb_miscdev.parent = &dev->dev;
 
 	ret = misc_register(&etb_miscdev);
@@ -395,25 +411,19 @@ static int __devinit etb_probe(struct amba_device *dev, const struct amba_id *id
 	else
 		clk_enable(t->emu_clk);
 
-	etb_unlock(t);
-	t->etb_bufsz = etb_readl(t, ETBR_DEPTH);
-	dev_dbg(&dev->dev, "Size: %x\n", t->etb_bufsz);
-
-	/* make sure trace capture is disabled */
-	etb_writel(t, 0, ETBR_CTRL);
-	etb_writel(t, 0x1000, ETBR_FORMATTERCTRL);
-	etb_lock(t);
-
 	dev_dbg(&dev->dev, "ETB AMBA driver initialized.\n");
 
 out:
 	return ret;
 
 out_unmap:
+	mutex_lock(&t->mutex);
 	amba_set_drvdata(dev, NULL);
 	iounmap(t->etb_regs);
+	t->etb_regs = NULL;
 
 out_release:
+	mutex_unlock(&t->mutex);
 	amba_release_regions(dev);
 
 	return ret;
@@ -475,7 +485,10 @@ static ssize_t trace_running_store(struct kobject *kobj,
 		return -EINVAL;
 
 	mutex_lock(&tracer.mutex);
-	ret = value ? trace_start(&tracer) : trace_stop(&tracer);
+	if (!tracer.etb_regs)
+		ret = -ENODEV;
+	else
+		ret = value ? trace_start(&tracer) : trace_stop(&tracer);
 	mutex_unlock(&tracer.mutex);
 
 	return ret ? : n;
@@ -491,18 +504,25 @@ static ssize_t trace_info_show(struct kobject *kobj,
 	u32 etb_wa, etb_ra, etb_st, etb_fc, etm_ctrl, etm_st;
 	int datalen;
 
-	etb_unlock(&tracer);
-	datalen = etb_getdatalen(&tracer);
-	etb_wa = etb_readl(&tracer, ETBR_WRITEADDR);
-	etb_ra = etb_readl(&tracer, ETBR_READADDR);
-	etb_st = etb_readl(&tracer, ETBR_STATUS);
-	etb_fc = etb_readl(&tracer, ETBR_FORMATTERCTRL);
-	etb_lock(&tracer);
+	mutex_lock(&tracer.mutex);
+	if (tracer.etb_regs) {
+		etb_unlock(&tracer);
+		datalen = etb_getdatalen(&tracer);
+		etb_wa = etb_readl(&tracer, ETBR_WRITEADDR);
+		etb_ra = etb_readl(&tracer, ETBR_READADDR);
+		etb_st = etb_readl(&tracer, ETBR_STATUS);
+		etb_fc = etb_readl(&tracer, ETBR_FORMATTERCTRL);
+		etb_lock(&tracer);
+	} else {
+		etb_wa = etb_ra = etb_st = etb_fc = ~0;
+		datalen = -1;
+	}
 
 	etm_unlock(&tracer);
 	etm_ctrl = etm_readl(&tracer, ETMR_CTRL);
 	etm_st = etm_readl(&tracer, ETMR_STATUS);
 	etm_lock(&tracer);
+	mutex_unlock(&tracer.mutex);
 
 	return sprintf(buf, "Trace buffer len: %d\nComparator pairs: %d\n"
 			"ETBR_WRITEADDR:\t%08x\n"
@@ -652,7 +672,6 @@ static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id
 
 	amba_set_drvdata(dev, t);
 
-	mutex_init(&t->mutex);
 	t->dev = &dev->dev;
 	t->flags = TRACER_CYCLE_ACC | TRACER_TRACE_DATA;
 	t->etm_portsz = 1;
@@ -746,6 +765,8 @@ static int __init etm_init(void)
 {
 	int retval;
 
+	mutex_init(&tracer.mutex);
+
 	retval = amba_driver_register(&etb_driver);
 	if (retval) {
 		printk(KERN_ERR "Failed to register etb\n");
-- 
1.7.3.2.146.gca209


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

* [PATCH 07/15] ARM: etm: Return the entire trace buffer if it is empty after reset
  2012-06-13  2:01 [PATCH 00/15][RFC] Android ETM driver changes John Stultz
                   ` (5 preceding siblings ...)
  2012-06-13  2:01 ` [PATCH 06/15] ARM: etm: Add some missing locks and error checks John Stultz
@ 2012-06-13  2:01 ` John Stultz
  2012-06-13  2:01 ` [PATCH 08/15] ARM: etm: Support multiple ETMs/PTMs John Stultz
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 16+ messages in thread
From: John Stultz @ 2012-06-13  2:01 UTC (permalink / raw)
  To: LKML
  Cc: Arve Hjønnevåg, Russell King, Paul Gortmaker,
	Alexander Shishkin, Mathieu Poirier, John Stultz

From: Arve Hjønnevåg <arve@android.com>

On some SOCs the read and write pointer are reset when the chip
resets, but the trace buffer content is preserved. If the status
bits indicates that the buffer is empty and we have never started
tracing, assume the buffer is full instead. This can be useful
if the system rebooted from a watchdog reset.

CC: Russell King <linux@arm.linux.org.uk>
CC: Paul Gortmaker <paul.gortmaker@windriver.com>
CC: Alexander Shishkin <alexander.shishkin@linux.intel.com>
CC: Mathieu Poirier <mathieu.poirier@linaro.org>

Acked-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: Arve Hjønnevåg <arve@android.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 arch/arm/kernel/etm.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index 3d21cf6..74444e5 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -45,6 +45,7 @@ struct tracectx {
 	unsigned long	range_end;
 	unsigned long	data_range_start;
 	unsigned long	data_range_end;
+	bool		dump_initial_etb;
 	struct device	*dev;
 	struct clk	*emu_clk;
 	struct mutex	mutex;
@@ -106,6 +107,7 @@ static int trace_start(struct tracectx *t)
 
 	etb_unlock(t);
 
+	t->dump_initial_etb = false;
 	etb_writel(t, 0, ETBR_WRITEADDR);
 	etb_writel(t, 0, ETBR_FORMATTERCTRL);
 	etb_writel(t, 1, ETBR_CTRL);
@@ -312,6 +314,8 @@ static ssize_t etb_read(struct file *file, char __user *data,
 	etb_unlock(t);
 
 	total = etb_getdatalen(t);
+	if (total == 0 && t->dump_initial_etb)
+		total = t->etb_bufsz;
 	if (total == t->etb_bufsz)
 		first = etb_readl(t, ETBR_WRITEADDR);
 
@@ -386,6 +390,7 @@ static int __devinit etb_probe(struct amba_device *dev, const struct amba_id *id
 		goto out_release;
 	}
 
+	t->dump_initial_etb = true;
 	amba_set_drvdata(dev, t);
 
 	etb_unlock(t);
-- 
1.7.3.2.146.gca209


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

* [PATCH 08/15] ARM: etm: Support multiple ETMs/PTMs.
  2012-06-13  2:01 [PATCH 00/15][RFC] Android ETM driver changes John Stultz
                   ` (6 preceding siblings ...)
  2012-06-13  2:01 ` [PATCH 07/15] ARM: etm: Return the entire trace buffer if it is empty after reset John Stultz
@ 2012-06-13  2:01 ` John Stultz
  2012-06-13  2:01 ` [PATCH 09/15] ARM: etm: Power down etm(s) when tracing is not enabled John Stultz
  2012-06-28 16:13 ` [PATCH 00/15][RFC] Android ETM driver changes Linus Walleij
  9 siblings, 0 replies; 16+ messages in thread
From: John Stultz @ 2012-06-13  2:01 UTC (permalink / raw)
  To: LKML
  Cc: Arve Hjønnevåg, Russell King, Paul Gortmaker,
	Alexander Shishkin, Mathieu Poirier, John Stultz

From: Arve Hjønnevåg <arve@android.com>

If more than one ETM or PTM are present, configure all of them
and enable the formatter in the ETB. This allows tracing on dual
core systems (e.g. omap4).

CC: Russell King <linux@arm.linux.org.uk>
CC: Paul Gortmaker <paul.gortmaker@windriver.com>
CC: Alexander Shishkin <alexander.shishkin@linux.intel.com>
CC: Mathieu Poirier <mathieu.poirier@linaro.org>

Acked-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: Arve Hjønnevåg <arve@android.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 arch/arm/include/asm/hardware/coresight.h |   16 ++-
 arch/arm/kernel/etm.c                     |  234 +++++++++++++++++++----------
 2 files changed, 166 insertions(+), 84 deletions(-)

diff --git a/arch/arm/include/asm/hardware/coresight.h b/arch/arm/include/asm/hardware/coresight.h
index 6ea507f..6643d6c 100644
--- a/arch/arm/include/asm/hardware/coresight.h
+++ b/arch/arm/include/asm/hardware/coresight.h
@@ -25,9 +25,9 @@
 
 #define TRACER_TIMEOUT 10000
 
-#define etm_writel(t, v, x) \
-	(__raw_writel((v), (t)->etm_regs + (x)))
-#define etm_readl(t, x) (__raw_readl((t)->etm_regs + (x)))
+#define etm_writel(t, id, v, x) \
+	(__raw_writel((v), (t)->etm_regs[(id)] + (x)))
+#define etm_readl(t, id, x) (__raw_readl((t)->etm_regs[(id)] + (x)))
 
 /* CoreSight Management Registers */
 #define CSMR_LOCKACCESS 0xfb0
@@ -126,6 +126,8 @@
 				ETMCTRL_BRANCH_OUTPUT | \
 				ETMCTRL_DO_CONTEXTID)
 
+#define ETMR_TRACEIDR		0x200
+
 /* ETM management registers, "ETM Architecture", 3.5.24 */
 #define ETMMR_OSLAR	0x300
 #define ETMMR_OSLSR	0x304
@@ -148,14 +150,16 @@
 #define ETBFF_TRIGIN		BIT(8)
 #define ETBFF_TRIGEVT		BIT(9)
 #define ETBFF_TRIGFL		BIT(10)
+#define ETBFF_STOPFL		BIT(12)
 
 #define etb_writel(t, v, x) \
 	(__raw_writel((v), (t)->etb_regs + (x)))
 #define etb_readl(t, x) (__raw_readl((t)->etb_regs + (x)))
 
-#define etm_lock(t) do { etm_writel((t), 0, CSMR_LOCKACCESS); } while (0)
-#define etm_unlock(t) \
-	do { etm_writel((t), UNLOCK_MAGIC, CSMR_LOCKACCESS); } while (0)
+#define etm_lock(t, id) \
+	do { etm_writel((t), (id), 0, CSMR_LOCKACCESS); } while (0)
+#define etm_unlock(t, id) \
+	do { etm_writel((t), (id), UNLOCK_MAGIC, CSMR_LOCKACCESS); } while (0)
 
 #define etb_lock(t) do { etb_writel((t), 0, CSMR_LOCKACCESS); } while (0)
 #define etb_unlock(t) \
diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index 74444e5..e3309ea 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/io.h>
+#include <linux/slab.h>
 #include <linux/sysrq.h>
 #include <linux/device.h>
 #include <linux/clk.h>
@@ -37,10 +38,12 @@ MODULE_AUTHOR("Alexander Shishkin");
 struct tracectx {
 	unsigned int	etb_bufsz;
 	void __iomem	*etb_regs;
-	void __iomem	*etm_regs;
+	void __iomem	**etm_regs;
+	int		etm_regs_count;
 	unsigned long	flags;
 	int		ncmppairs;
 	int		etm_portsz;
+	u32		etb_fc;
 	unsigned long	range_start;
 	unsigned long	range_end;
 	unsigned long	data_range_start;
@@ -61,7 +64,7 @@ static inline bool trace_isrunning(struct tracectx *t)
 	return !!(t->flags & TRACER_RUNNING);
 }
 
-static int etm_setup_address_range(struct tracectx *t, int n,
+static int etm_setup_address_range(struct tracectx *t, int id, int n,
 		unsigned long start, unsigned long end, int exclude, int data)
 {
 	u32 flags = ETMAAT_ARM | ETMAAT_IGNCONTEXTID | ETMAAT_IGNSECURITY |
@@ -80,41 +83,31 @@ static int etm_setup_address_range(struct tracectx *t, int n,
 		flags |= ETMAAT_IEXEC;
 
 	/* first comparator for the range */
-	etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2));
-	etm_writel(t, start, ETMR_COMP_VAL(n * 2));
+	etm_writel(t, id, flags, ETMR_COMP_ACC_TYPE(n * 2));
+	etm_writel(t, id, start, ETMR_COMP_VAL(n * 2));
 
 	/* second comparator is right next to it */
-	etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2 + 1));
-	etm_writel(t, end, ETMR_COMP_VAL(n * 2 + 1));
+	etm_writel(t, id, flags, ETMR_COMP_ACC_TYPE(n * 2 + 1));
+	etm_writel(t, id, end, ETMR_COMP_VAL(n * 2 + 1));
 
 	if (data) {
 		flags = exclude ? ETMVDC3_EXCLONLY : 0;
 		if (exclude)
 			n += 8;
-		etm_writel(t, flags | BIT(n), ETMR_VIEWDATACTRL3);
+		etm_writel(t, id, flags | BIT(n), ETMR_VIEWDATACTRL3);
 	} else {
 		flags = exclude ? ETMTE_INCLEXCL : 0;
-		etm_writel(t, flags | (1 << n), ETMR_TRACEENCTRL);
+		etm_writel(t, id, flags | (1 << n), ETMR_TRACEENCTRL);
 	}
 
 	return 0;
 }
 
-static int trace_start(struct tracectx *t)
+static int trace_start_etm(struct tracectx *t, int id)
 {
 	u32 v;
 	unsigned long timeout = TRACER_TIMEOUT;
 
-	etb_unlock(t);
-
-	t->dump_initial_etb = false;
-	etb_writel(t, 0, ETBR_WRITEADDR);
-	etb_writel(t, 0, ETBR_FORMATTERCTRL);
-	etb_writel(t, 1, ETBR_CTRL);
-
-	etb_lock(t);
-
-	/* configure etm */
 	v = ETMCTRL_OPTS | ETMCTRL_PROGRAM | ETMCTRL_PORTSIZE(t->etm_portsz);
 
 	if (t->flags & TRACER_CYCLE_ACC)
@@ -123,79 +116,122 @@ static int trace_start(struct tracectx *t)
 	if (t->flags & TRACER_TRACE_DATA)
 		v |= ETMCTRL_DATA_DO_ADDR;
 
-	etm_unlock(t);
+	etm_unlock(t, id);
 
-	etm_writel(t, v, ETMR_CTRL);
+	etm_writel(t, id, v, ETMR_CTRL);
 
-	while (!(etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
+	while (!(etm_readl(t, id, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
 		;
 	if (!timeout) {
 		dev_dbg(t->dev, "Waiting for progbit to assert timed out\n");
-		etm_lock(t);
+		etm_lock(t, id);
 		return -EFAULT;
 	}
 
 	if (t->range_start || t->range_end)
-		etm_setup_address_range(t, 1,
+		etm_setup_address_range(t, id, 1,
 					t->range_start, t->range_end, 0, 0);
 	else
-		etm_writel(t, ETMTE_INCLEXCL, ETMR_TRACEENCTRL);
+		etm_writel(t, id, ETMTE_INCLEXCL, ETMR_TRACEENCTRL);
 
-	etm_writel(t, 0, ETMR_TRACEENCTRL2);
-	etm_writel(t, 0, ETMR_TRACESSCTRL);
-	etm_writel(t, 0x6f, ETMR_TRACEENEVT);
+	etm_writel(t, id, 0, ETMR_TRACEENCTRL2);
+	etm_writel(t, id, 0, ETMR_TRACESSCTRL);
+	etm_writel(t, id, 0x6f, ETMR_TRACEENEVT);
 
-	etm_writel(t, 0, ETMR_VIEWDATACTRL1);
-	etm_writel(t, 0, ETMR_VIEWDATACTRL2);
+	etm_writel(t, id, 0, ETMR_VIEWDATACTRL1);
+	etm_writel(t, id, 0, ETMR_VIEWDATACTRL2);
 
 	if (t->data_range_start || t->data_range_end)
-		etm_setup_address_range(t, 2, t->data_range_start,
+		etm_setup_address_range(t, id, 2, t->data_range_start,
 					t->data_range_end, 0, 1);
 	else
-		etm_writel(t, ETMVDC3_EXCLONLY, ETMR_VIEWDATACTRL3);
+		etm_writel(t, id, ETMVDC3_EXCLONLY, ETMR_VIEWDATACTRL3);
 
-	etm_writel(t, 0x6f, ETMR_VIEWDATAEVT);
+	etm_writel(t, id, 0x6f, ETMR_VIEWDATAEVT);
 
 	v &= ~ETMCTRL_PROGRAM;
 	v |= ETMCTRL_PORTSEL;
 
-	etm_writel(t, v, ETMR_CTRL);
+	etm_writel(t, id, v, ETMR_CTRL);
 
 	timeout = TRACER_TIMEOUT;
-	while (etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM && --timeout)
+	while (etm_readl(t, id, ETMR_CTRL) & ETMCTRL_PROGRAM && --timeout)
 		;
 	if (!timeout) {
 		dev_dbg(t->dev, "Waiting for progbit to deassert timed out\n");
-		etm_lock(t);
+		etm_lock(t, id);
 		return -EFAULT;
 	}
 
-	etm_lock(t);
+	etm_lock(t, id);
+	return 0;
+}
+
+static int trace_start(struct tracectx *t)
+{
+	int ret;
+	int id;
+	u32 etb_fc = t->etb_fc;
+
+	etb_unlock(t);
+
+	t->dump_initial_etb = false;
+	etb_writel(t, 0, ETBR_WRITEADDR);
+	etb_writel(t, etb_fc, ETBR_FORMATTERCTRL);
+	etb_writel(t, 1, ETBR_CTRL);
+
+	etb_lock(t);
+
+	/* configure etm(s) */
+	for (id = 0; id < t->etm_regs_count; id++) {
+		ret = trace_start_etm(t, id);
+		if (ret)
+			return ret;
+	}
 
 	t->flags |= TRACER_RUNNING;
 
 	return 0;
 }
 
-static int trace_stop(struct tracectx *t)
+static int trace_stop_etm(struct tracectx *t, int id)
 {
 	unsigned long timeout = TRACER_TIMEOUT;
 
-	etm_unlock(t);
+	etm_unlock(t, id);
 
-	etm_writel(t, 0x440, ETMR_CTRL);
-	while (!(etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
+	etm_writel(t, id, 0x440, ETMR_CTRL);
+	while (!(etm_readl(t, id, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
 		;
 	if (!timeout) {
 		dev_dbg(t->dev, "Waiting for progbit to assert timed out\n");
-		etm_lock(t);
+		etm_lock(t, id);
 		return -EFAULT;
 	}
 
-	etm_lock(t);
+	etm_lock(t, id);
+	return 0;
+}
+
+static int trace_stop(struct tracectx *t)
+{
+	int id;
+	int ret;
+	unsigned long timeout = TRACER_TIMEOUT;
+	u32 etb_fc = t->etb_fc;
+
+	for (id = 0; id < t->etm_regs_count; id++) {
+		ret = trace_stop_etm(t, id);
+		if (ret)
+			return ret;
+	}
 
 	etb_unlock(t);
-	etb_writel(t, ETBFF_MANUAL_FLUSH, ETBR_FORMATTERCTRL);
+	if (etb_fc) {
+		etb_fc |= ETBFF_STOPFL;
+		etb_writel(t, t->etb_fc, ETBR_FORMATTERCTRL);
+	}
+	etb_writel(t, etb_fc | ETBFF_MANUAL_FLUSH, ETBR_FORMATTERCTRL);
 
 	timeout = TRACER_TIMEOUT;
 	while (etb_readl(t, ETBR_FORMATTERCTRL) &
@@ -390,6 +426,7 @@ static int __devinit etb_probe(struct amba_device *dev, const struct amba_id *id
 		goto out_release;
 	}
 
+	t->dev = &dev->dev;
 	t->dump_initial_etb = true;
 	amba_set_drvdata(dev, t);
 
@@ -508,6 +545,8 @@ static ssize_t trace_info_show(struct kobject *kobj,
 {
 	u32 etb_wa, etb_ra, etb_st, etb_fc, etm_ctrl, etm_st;
 	int datalen;
+	int id;
+	int ret;
 
 	mutex_lock(&tracer.mutex);
 	if (tracer.etb_regs) {
@@ -523,28 +562,33 @@ static ssize_t trace_info_show(struct kobject *kobj,
 		datalen = -1;
 	}
 
-	etm_unlock(&tracer);
-	etm_ctrl = etm_readl(&tracer, ETMR_CTRL);
-	etm_st = etm_readl(&tracer, ETMR_STATUS);
-	etm_lock(&tracer);
-	mutex_unlock(&tracer.mutex);
-
-	return sprintf(buf, "Trace buffer len: %d\nComparator pairs: %d\n"
+	ret = sprintf(buf, "Trace buffer len: %d\nComparator pairs: %d\n"
 			"ETBR_WRITEADDR:\t%08x\n"
 			"ETBR_READADDR:\t%08x\n"
 			"ETBR_STATUS:\t%08x\n"
-			"ETBR_FORMATTERCTRL:\t%08x\n"
-			"ETMR_CTRL:\t%08x\n"
-			"ETMR_STATUS:\t%08x\n",
+			"ETBR_FORMATTERCTRL:\t%08x\n",
 			datalen,
 			tracer.ncmppairs,
 			etb_wa,
 			etb_ra,
 			etb_st,
-			etb_fc,
+			etb_fc
+			);
+
+	for (id = 0; id < tracer.etm_regs_count; id++) {
+		etm_unlock(&tracer, id);
+		etm_ctrl = etm_readl(&tracer, id, ETMR_CTRL);
+		etm_st = etm_readl(&tracer, id, ETMR_STATUS);
+		etm_lock(&tracer, id);
+		ret += sprintf(buf + ret, "ETMR_CTRL:\t%08x\n"
+			"ETMR_STATUS:\t%08x\n",
 			etm_ctrl,
 			etm_st
 			);
+	}
+	mutex_unlock(&tracer.mutex);
+
+	return ret;
 }
 
 static struct kobj_attribute trace_info_attr =
@@ -658,37 +702,46 @@ static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id
 {
 	struct tracectx *t = &tracer;
 	int ret = 0;
+	void __iomem **new_regs;
+	int new_count;
 
-	if (t->etm_regs) {
-		dev_dbg(&dev->dev, "ETM already initialized\n");
-		ret = -EBUSY;
+	mutex_lock(&t->mutex);
+	new_count = t->etm_regs_count + 1;
+	new_regs = krealloc(t->etm_regs,
+				sizeof(t->etm_regs[0]) * new_count, GFP_KERNEL);
+
+	if (!new_regs) {
+		dev_dbg(&dev->dev, "Failed to allocate ETM register array\n");
+		ret = -ENOMEM;
 		goto out;
 	}
+	t->etm_regs = new_regs;
 
 	ret = amba_request_regions(dev, NULL);
 	if (ret)
 		goto out;
 
-	t->etm_regs = ioremap_nocache(dev->res.start, resource_size(&dev->res));
-	if (!t->etm_regs) {
+	t->etm_regs[t->etm_regs_count] =
+		ioremap_nocache(dev->res.start, resource_size(&dev->res));
+	if (!t->etm_regs[t->etm_regs_count]) {
 		ret = -ENOMEM;
 		goto out_release;
 	}
 
-	amba_set_drvdata(dev, t);
+	amba_set_drvdata(dev, t->etm_regs[t->etm_regs_count]);
 
-	t->dev = &dev->dev;
 	t->flags = TRACER_CYCLE_ACC | TRACER_TRACE_DATA;
 	t->etm_portsz = 1;
 
-	etm_unlock(t);
-	(void)etm_readl(t, ETMMR_PDSR);
+	etm_unlock(t, t->etm_regs_count);
+	(void)etm_readl(t, t->etm_regs_count, ETMMR_PDSR);
 	/* dummy first read */
-	(void)etm_readl(&tracer, ETMMR_OSSRR);
+	(void)etm_readl(&tracer, t->etm_regs_count, ETMMR_OSSRR);
 
-	t->ncmppairs = etm_readl(t, ETMR_CONFCODE) & 0xf;
-	etm_writel(t, 0x440, ETMR_CTRL);
-	etm_lock(t);
+	t->ncmppairs = etm_readl(t, t->etm_regs_count, ETMR_CONFCODE) & 0xf;
+	etm_writel(t, t->etm_regs_count, 0x440, ETMR_CTRL);
+	etm_writel(t, t->etm_regs_count, new_count, ETMR_TRACEIDR);
+	etm_lock(t, t->etm_regs_count);
 
 	ret = sysfs_create_file(&dev->dev.kobj,
 			&trace_running_attr.attr);
@@ -713,31 +766,34 @@ static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id
 		dev_dbg(&dev->dev,
 			"Failed to create trace_data_range in sysfs\n");
 
-	dev_dbg(t->dev, "ETM AMBA driver initialized.\n");
+	dev_dbg(&dev->dev, "ETM AMBA driver initialized.\n");
+
+	/* Enable formatter if there are multiple trace sources */
+	if (new_count > 1)
+		t->etb_fc = ETBFF_ENFCONT | ETBFF_ENFTC;
+
+	t->etm_regs_count = new_count;
 
 out:
+	mutex_unlock(&t->mutex);
 	return ret;
 
 out_unmap:
 	amba_set_drvdata(dev, NULL);
-	iounmap(t->etm_regs);
+	iounmap(t->etm_regs[t->etm_regs_count]);
 
 out_release:
 	amba_release_regions(dev);
 
+	mutex_unlock(&t->mutex);
 	return ret;
 }
 
 static int etm_remove(struct amba_device *dev)
 {
-	struct tracectx *t = amba_get_drvdata(dev);
-
-	amba_set_drvdata(dev, NULL);
-
-	iounmap(t->etm_regs);
-	t->etm_regs = NULL;
-
-	amba_release_regions(dev);
+	int i;
+	struct tracectx *t = &tracer;
+	void __iomem	*etm_regs = amba_get_drvdata(dev);
 
 	sysfs_remove_file(&dev->dev.kobj, &trace_running_attr.attr);
 	sysfs_remove_file(&dev->dev.kobj, &trace_info_attr.attr);
@@ -745,6 +801,24 @@ static int etm_remove(struct amba_device *dev)
 	sysfs_remove_file(&dev->dev.kobj, &trace_range_attr.attr);
 	sysfs_remove_file(&dev->dev.kobj, &trace_data_range_attr.attr);
 
+	amba_set_drvdata(dev, NULL);
+
+	mutex_lock(&t->mutex);
+	for (i = 0; i < t->etm_regs_count; i++)
+		if (t->etm_regs[i] == etm_regs)
+			break;
+	for (; i < t->etm_regs_count - 1; i++)
+		t->etm_regs[i] = t->etm_regs[i + 1];
+	t->etm_regs_count--;
+	if (!t->etm_regs_count) {
+		kfree(t->etm_regs);
+		t->etm_regs = NULL;
+	}
+	mutex_unlock(&t->mutex);
+
+	iounmap(etm_regs);
+	amba_release_regions(dev);
+
 	return 0;
 }
 
@@ -753,6 +827,10 @@ static struct amba_id etm_ids[] = {
 		.id	= 0x0003b921,
 		.mask	= 0x0007ffff,
 	},
+	{
+		.id	= 0x0003b950,
+		.mask	= 0x0007ffff,
+	},
 	{ 0, 0 },
 };
 
-- 
1.7.3.2.146.gca209


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

* [PATCH 09/15] ARM: etm: Power down etm(s) when tracing is not enabled
  2012-06-13  2:01 [PATCH 00/15][RFC] Android ETM driver changes John Stultz
                   ` (7 preceding siblings ...)
  2012-06-13  2:01 ` [PATCH 08/15] ARM: etm: Support multiple ETMs/PTMs John Stultz
@ 2012-06-13  2:01 ` John Stultz
  2012-06-28 16:13 ` [PATCH 00/15][RFC] Android ETM driver changes Linus Walleij
  9 siblings, 0 replies; 16+ messages in thread
From: John Stultz @ 2012-06-13  2:01 UTC (permalink / raw)
  To: LKML
  Cc: Arve Hjønnevåg, Russell King, Paul Gortmaker,
	Alexander Shishkin, Mathieu Poirier, John Stultz

From: Arve Hjønnevåg <arve@android.com>

Without this change a saw an 18% increase in idle power consumption
on one deivce when trace support is compiled into the kernel. Now
I see the same increase only when tracing.

CC: Russell King <linux@arm.linux.org.uk>
CC: Paul Gortmaker <paul.gortmaker@windriver.com>
CC: Alexander Shishkin <alexander.shishkin@linux.intel.com>
CC: Mathieu Poirier <mathieu.poirier@linaro.org>

Acked-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: Arve Hjønnevåg <arve@android.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 arch/arm/kernel/etm.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index e3309ea..66bf592 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -200,7 +200,7 @@ static int trace_stop_etm(struct tracectx *t, int id)
 
 	etm_unlock(t, id);
 
-	etm_writel(t, id, 0x440, ETMR_CTRL);
+	etm_writel(t, id, 0x441, ETMR_CTRL);
 	while (!(etm_readl(t, id, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
 		;
 	if (!timeout) {
@@ -739,7 +739,7 @@ static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id
 	(void)etm_readl(&tracer, t->etm_regs_count, ETMMR_OSSRR);
 
 	t->ncmppairs = etm_readl(t, t->etm_regs_count, ETMR_CONFCODE) & 0xf;
-	etm_writel(t, t->etm_regs_count, 0x440, ETMR_CTRL);
+	etm_writel(t, t->etm_regs_count, 0x441, ETMR_CTRL);
 	etm_writel(t, t->etm_regs_count, new_count, ETMR_TRACEIDR);
 	etm_lock(t, t->etm_regs_count);
 
-- 
1.7.3.2.146.gca209


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

* Re: [PATCH 01/15] ARM: etm: Don't require clock control
  2012-06-13  2:01 ` [PATCH 01/15] ARM: etm: Don't require clock control John Stultz
@ 2012-06-13  8:33   ` Paul Mundt
  2012-06-13 23:09     ` John Stultz
  0 siblings, 1 reply; 16+ messages in thread
From: Paul Mundt @ 2012-06-13  8:33 UTC (permalink / raw)
  To: John Stultz
  Cc: LKML, Arve Hj??nnev??g, Russell King, Paul Gortmaker,
	Alexander Shishkin, Mathieu Poirier

On Tue, Jun 12, 2012 at 07:01:19PM -0700, John Stultz wrote:
> diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
> index 36d20bd..bd295e8 100644
> --- a/arch/arm/kernel/etm.c
> +++ b/arch/arm/kernel/etm.c
> @@ -362,13 +362,12 @@ static int __devinit etb_probe(struct amba_device *dev, const struct amba_id *id
>  	if (ret)
>  		goto out_unmap;
>  
> +	/* Get optional clock. Currently used to select clock source on omap3 */
>  	t->emu_clk = clk_get(&dev->dev, "emu_src_ck");
> -	if (IS_ERR(t->emu_clk)) {
> +	if (IS_ERR(t->emu_clk))
>  		dev_dbg(&dev->dev, "Failed to obtain emu_src_ck.\n");
> -		return -EFAULT;
> -	}
> -
> -	clk_enable(t->emu_clk);
> +	else
> +		clk_enable(t->emu_clk);
>  
Optionally you could just:

	if (IS_ERR(t->emu_clk))
		t->emu_clk = NULL;

and use the clk API as you were, as it does handle NULL being passed in.

In this case you don't have too many callsites to worry about, but it's
reasonably convenient to be able to pass a NULL clk pointer around
without constant special-casing when those start to balloon up.

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

* Re: [PATCH 01/15] ARM: etm: Don't require clock control
  2012-06-13  8:33   ` Paul Mundt
@ 2012-06-13 23:09     ` John Stultz
  0 siblings, 0 replies; 16+ messages in thread
From: John Stultz @ 2012-06-13 23:09 UTC (permalink / raw)
  To: Paul Mundt
  Cc: LKML, Arve Hj??nnev??g, Russell King, Paul Gortmaker,
	Alexander Shishkin, Mathieu Poirier

On 06/13/2012 01:33 AM, Paul Mundt wrote:
> On Tue, Jun 12, 2012 at 07:01:19PM -0700, John Stultz wrote:
>> diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
>> index 36d20bd..bd295e8 100644
>> --- a/arch/arm/kernel/etm.c
>> +++ b/arch/arm/kernel/etm.c
>> @@ -362,13 +362,12 @@ static int __devinit etb_probe(struct amba_device *dev, const struct amba_id *id
>>   	if (ret)
>>   		goto out_unmap;
>>
>> +	/* Get optional clock. Currently used to select clock source on omap3 */
>>   	t->emu_clk = clk_get(&dev->dev, "emu_src_ck");
>> -	if (IS_ERR(t->emu_clk)) {
>> +	if (IS_ERR(t->emu_clk))
>>   		dev_dbg(&dev->dev, "Failed to obtain emu_src_ck.\n");
>> -		return -EFAULT;
>> -	}
>> -
>> -	clk_enable(t->emu_clk);
>> +	else
>> +		clk_enable(t->emu_clk);
>>
> Optionally you could just:
>
> 	if (IS_ERR(t->emu_clk))
> 		t->emu_clk = NULL;
>
> and use the clk API as you were, as it does handle NULL being passed in.
>
> In this case you don't have too many callsites to worry about, but it's
> reasonably convenient to be able to pass a NULL clk pointer around
> without constant special-casing when those start to balloon up.
>
Hrm. That's a good trick to remember for the future!

Although in this case I'm not sure it wins much (since the re-adding of 
the braces and the null assignment is still more code then using the 
else).  So unless this is a major style problem for you (and do let me 
know if it is), I'll probably leave it alone.

thanks
-john


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

* Re: [PATCH 00/15][RFC] Android ETM driver changes
  2012-06-13  2:01 [PATCH 00/15][RFC] Android ETM driver changes John Stultz
                   ` (8 preceding siblings ...)
  2012-06-13  2:01 ` [PATCH 09/15] ARM: etm: Power down etm(s) when tracing is not enabled John Stultz
@ 2012-06-28 16:13 ` Linus Walleij
  2012-06-29 20:25   ` John Stultz
  9 siblings, 1 reply; 16+ messages in thread
From: Linus Walleij @ 2012-06-28 16:13 UTC (permalink / raw)
  To: John Stultz
  Cc: LKML, Russell King, Paul Gortmaker, Alexander Shishkin,
	Arve Hjønnevåg

On Wed, Jun 13, 2012 at 4:01 AM, John Stultz <john.stultz@linaro.org> wrote:

> The Android kernel tree has a number of changes to the ETM driver.
> Arve sent the first 9 of these to the list over a year ago and
> got very little response.
>
> I didn't want these to get lost, so I pinged Alexander about
> these privately and he stated that he wasn't actively
> maintaining the driver, but after skimming the entire set
> acked the series and suggested I send it on to Russel for
> review and possible inclusion.
>
> So here they are. Please let me know if there are any
> objections to merging these, or if further changes are
> needed.

I finally reviewed them, sorry for the lag.

In all this is very useful stuff, maybe people just don't realize how
useful it really is. I suggest you to write a small doc in
Documentation/arm/etm.txt on how to get started etc.

Thanks for your efforts!

Yours,
Linus Walleij

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

* Re: [PATCH 00/15][RFC] Android ETM driver changes
  2012-06-28 16:13 ` [PATCH 00/15][RFC] Android ETM driver changes Linus Walleij
@ 2012-06-29 20:25   ` John Stultz
  0 siblings, 0 replies; 16+ messages in thread
From: John Stultz @ 2012-06-29 20:25 UTC (permalink / raw)
  To: Linus Walleij
  Cc: LKML, Russell King, Paul Gortmaker, Alexander Shishkin,
	Arve Hjønnevåg

On 06/28/2012 09:13 AM, Linus Walleij wrote:
> On Wed, Jun 13, 2012 at 4:01 AM, John Stultz <john.stultz@linaro.org> wrote:
>
>> The Android kernel tree has a number of changes to the ETM driver.
>> Arve sent the first 9 of these to the list over a year ago and
>> got very little response.
>>
>> I didn't want these to get lost, so I pinged Alexander about
>> these privately and he stated that he wasn't actively
>> maintaining the driver, but after skimming the entire set
>> acked the series and suggested I send it on to Russel for
>> review and possible inclusion.
>>
>> So here they are. Please let me know if there are any
>> objections to merging these, or if further changes are
>> needed.
> I finally reviewed them, sorry for the lag.
>
> In all this is very useful stuff, maybe people just don't realize how
> useful it really is. I suggest you to write a small doc in
> Documentation/arm/etm.txt on how to get started etc.
>
> Thanks for your efforts!
Thanks for the review!  I'll try to work with Arve to see if I can help 
address some of the issues you pointed out and to improve the documentation.

thanks
-john



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

* Re: [PATCH 01/15] ARM: etm: Don't require clock control
  2012-06-20 22:47 ` [PATCH 01/15] ARM: etm: Don't require clock control John Stultz
@ 2012-06-28 15:47   ` Linus Walleij
  0 siblings, 0 replies; 16+ messages in thread
From: Linus Walleij @ 2012-06-28 15:47 UTC (permalink / raw)
  To: John Stultz
  Cc: LKML, Arve Hjønnevåg, Russell King, Paul Gortmaker,
	Alexander Shishkin

On Thu, Jun 21, 2012 at 12:47 AM, John Stultz <john.stultz@linaro.org> wrote:

> -       clk_enable(t->emu_clk);
> +       else
> +               clk_enable(t->emu_clk);

Take this opportunity to use clk_prepare_enable();

>        etb_unlock(t);
>        t->etb_bufsz = etb_readl(t, ETBR_DEPTH);
> @@ -403,8 +402,10 @@ static int etb_remove(struct amba_device *dev)
>        iounmap(t->etb_regs);
>        t->etb_regs = NULL;
>
> -       clk_disable(t->emu_clk);
> -       clk_put(t->emu_clk);
> +       if (!IS_ERR(t->emu_clk)) {
> +               clk_disable(t->emu_clk);

And clk_disable_uprepare() here.

> +               clk_put(t->emu_clk);
> +       }

After that it's
Acked-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

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

* [PATCH 01/15] ARM: etm: Don't require clock control
  2012-06-20 22:47 [PATCH 00/15] " John Stultz
@ 2012-06-20 22:47 ` John Stultz
  2012-06-28 15:47   ` Linus Walleij
  0 siblings, 1 reply; 16+ messages in thread
From: John Stultz @ 2012-06-20 22:47 UTC (permalink / raw)
  To: LKML
  Cc: Arve Hjønnevåg, Russell King, Paul Gortmaker,
	Alexander Shishkin, John Stultz

From: Arve Hjønnevåg <arve@android.com>

If clk_get fail, assume the etb does not need a separate clock.

CC: Russell King <linux@arm.linux.org.uk>
CC: Paul Gortmaker <paul.gortmaker@windriver.com>
CC: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Acked-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: Arve Hjønnevåg <arve@android.com>
Signed-off-by: John Stultz <john.stultz@linaro.org>
---
 arch/arm/kernel/etm.c |   15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index 36d20bd..bd295e8 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -362,13 +362,12 @@ static int __devinit etb_probe(struct amba_device *dev, const struct amba_id *id
 	if (ret)
 		goto out_unmap;
 
+	/* Get optional clock. Currently used to select clock source on omap3 */
 	t->emu_clk = clk_get(&dev->dev, "emu_src_ck");
-	if (IS_ERR(t->emu_clk)) {
+	if (IS_ERR(t->emu_clk))
 		dev_dbg(&dev->dev, "Failed to obtain emu_src_ck.\n");
-		return -EFAULT;
-	}
-
-	clk_enable(t->emu_clk);
+	else
+		clk_enable(t->emu_clk);
 
 	etb_unlock(t);
 	t->etb_bufsz = etb_readl(t, ETBR_DEPTH);
@@ -403,8 +402,10 @@ static int etb_remove(struct amba_device *dev)
 	iounmap(t->etb_regs);
 	t->etb_regs = NULL;
 
-	clk_disable(t->emu_clk);
-	clk_put(t->emu_clk);
+	if (!IS_ERR(t->emu_clk)) {
+		clk_disable(t->emu_clk);
+		clk_put(t->emu_clk);
+	}
 
 	amba_release_regions(dev);
 
-- 
1.7.9.5


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

end of thread, other threads:[~2012-06-29 20:26 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-13  2:01 [PATCH 00/15][RFC] Android ETM driver changes John Stultz
2012-06-13  2:01 ` [PATCH 01/15] ARM: etm: Don't require clock control John Stultz
2012-06-13  8:33   ` Paul Mundt
2012-06-13 23:09     ` John Stultz
2012-06-13  2:01 ` [PATCH 02/15] ARM: etm: Don't limit tracing to only non-secure code John Stultz
2012-06-13  2:01 ` [PATCH 03/15] ARM: etm: Don't try to clear the buffer full status after reading the buffer John Stultz
2012-06-13  2:01 ` [PATCH 04/15] ARM: etm: Allow range selection John Stultz
2012-06-13  2:01 ` [PATCH 05/15] ARM: etm: Configure data tracing John Stultz
2012-06-13  2:01 ` [PATCH 06/15] ARM: etm: Add some missing locks and error checks John Stultz
2012-06-13  2:01 ` [PATCH 07/15] ARM: etm: Return the entire trace buffer if it is empty after reset John Stultz
2012-06-13  2:01 ` [PATCH 08/15] ARM: etm: Support multiple ETMs/PTMs John Stultz
2012-06-13  2:01 ` [PATCH 09/15] ARM: etm: Power down etm(s) when tracing is not enabled John Stultz
2012-06-28 16:13 ` [PATCH 00/15][RFC] Android ETM driver changes Linus Walleij
2012-06-29 20:25   ` John Stultz
2012-06-20 22:47 [PATCH 00/15] " John Stultz
2012-06-20 22:47 ` [PATCH 01/15] ARM: etm: Don't require clock control John Stultz
2012-06-28 15:47   ` Linus Walleij

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.