Commit 5e5ff344 authored by Pratik Patel's avatar Pratik Patel Committed by Greg Kroah-Hartman

coresight-etm4x: Controls pertaining to the sequencer functions

Adding sysfs entries to access the sequencers related registers,
more specifically the sequencer state, the sequencer state
transition and the sequencer reset control registers.
Signed-off-by: default avatarPratik Patel <pratikp@codeaurora.org>
Signed-off-by: default avatarMathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 35c9b29b
...@@ -179,3 +179,28 @@ Date: April 2015 ...@@ -179,3 +179,28 @@ Date: April 2015
KernelVersion: 4.01 KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org> Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Used to setup address range comparator values. Description: (RW) Used to setup address range comparator values.
What: /sys/bus/coresight/devices/<memory_map>.etm/seq_idx
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Select which sequensor.
What: /sys/bus/coresight/devices/<memory_map>.etm/seq_state
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Use this to set, or read, the sequencer state.
What: /sys/bus/coresight/devices/<memory_map>.etm/seq_event
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Moves the sequencer state to a specific state.
What: /sys/bus/coresight/devices/<memory_map>.etm/seq_reset_event
Date: April 2015
KernelVersion: 4.01
Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Moves the sequencer to state 0 when a programmed event
occurs.
...@@ -1442,6 +1442,131 @@ static ssize_t addr_context_store(struct device *dev, ...@@ -1442,6 +1442,131 @@ static ssize_t addr_context_store(struct device *dev,
} }
static DEVICE_ATTR_RW(addr_context); static DEVICE_ATTR_RW(addr_context);
static ssize_t seq_idx_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
val = drvdata->seq_idx;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
static ssize_t seq_idx_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t size)
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
if (kstrtoul(buf, 16, &val))
return -EINVAL;
if (val >= drvdata->nrseqstate - 1)
return -EINVAL;
/*
* Use spinlock to ensure index doesn't change while it gets
* dereferenced multiple times within a spinlock block elsewhere.
*/
spin_lock(&drvdata->spinlock);
drvdata->seq_idx = val;
spin_unlock(&drvdata->spinlock);
return size;
}
static DEVICE_ATTR_RW(seq_idx);
static ssize_t seq_state_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
val = drvdata->seq_state;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
static ssize_t seq_state_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t size)
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
if (kstrtoul(buf, 16, &val))
return -EINVAL;
if (val >= drvdata->nrseqstate)
return -EINVAL;
drvdata->seq_state = val;
return size;
}
static DEVICE_ATTR_RW(seq_state);
static ssize_t seq_event_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
u8 idx;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
spin_lock(&drvdata->spinlock);
idx = drvdata->seq_idx;
val = drvdata->seq_ctrl[idx];
spin_unlock(&drvdata->spinlock);
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
static ssize_t seq_event_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t size)
{
u8 idx;
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
if (kstrtoul(buf, 16, &val))
return -EINVAL;
spin_lock(&drvdata->spinlock);
idx = drvdata->seq_idx;
/* RST, bits[7:0] */
drvdata->seq_ctrl[idx] = val & 0xFF;
spin_unlock(&drvdata->spinlock);
return size;
}
static DEVICE_ATTR_RW(seq_event);
static ssize_t seq_reset_event_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
val = drvdata->seq_rst;
return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
}
static ssize_t seq_reset_event_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t size)
{
unsigned long val;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
if (kstrtoul(buf, 16, &val))
return -EINVAL;
if (!(drvdata->nrseqstate))
return -EINVAL;
drvdata->seq_rst = val & ETMv4_EVENT_MASK;
return size;
}
static DEVICE_ATTR_RW(seq_reset_event);
static ssize_t cpu_show(struct device *dev, static ssize_t cpu_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
...@@ -1484,6 +1609,10 @@ static struct attribute *coresight_etmv4_attrs[] = { ...@@ -1484,6 +1609,10 @@ static struct attribute *coresight_etmv4_attrs[] = {
&dev_attr_addr_stop.attr, &dev_attr_addr_stop.attr,
&dev_attr_addr_ctxtype.attr, &dev_attr_addr_ctxtype.attr,
&dev_attr_addr_context.attr, &dev_attr_addr_context.attr,
&dev_attr_seq_idx.attr,
&dev_attr_seq_state.attr,
&dev_attr_seq_event.attr,
&dev_attr_seq_reset_event.attr,
&dev_attr_cpu.attr, &dev_attr_cpu.attr,
NULL, NULL,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment