mirror of
https://github.com/torvalds/linux.git
synced 2026-08-02 13:22:02 +02:00
coresight: byte-cntr: Add support for streaming interface for ETR
Add support for a streaming interface for TMC ETR to allow for continuous log collection to secondary storage. An interrupt based mechanism is used to stream out the data from the device. The streaming interface cannot be used in conjunction with the traditional ETR read operation. And remove the support of sw usb from byte-cntr. Change-Id: I23f30f2df72e58b13481a2f230212534745edadb Signed-off-by: Tao Zhang <quic_taozha@quicinc.com> Signed-off-by: Mao Jinlong <quic_jinlmao@quicinc.com>
This commit is contained in:
parent
018a23891f
commit
d5996184e9
|
|
@ -9,7 +9,7 @@ coresight-y := coresight-core.o coresight-etm-perf.o coresight-platform.o \
|
|||
coresight-syscfg-configfs.o
|
||||
obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o
|
||||
coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \
|
||||
coresight-tmc-etr.o
|
||||
coresight-tmc-etr.o coresight-byte-cntr.o
|
||||
obj-$(CONFIG_CORESIGHT_SINK_TPIU) += coresight-tpiu.o
|
||||
obj-$(CONFIG_CORESIGHT_SINK_ETBV10) += coresight-etb10.o
|
||||
obj-$(CONFIG_CORESIGHT_LINKS_AND_SINKS) += coresight-funnel.o \
|
||||
|
|
|
|||
344
drivers/hwtracing/coresight/coresight-byte-cntr.c
Normal file
344
drivers/hwtracing/coresight/coresight-byte-cntr.c
Normal file
|
|
@ -0,0 +1,344 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/property.h>
|
||||
|
||||
#include "coresight-priv.h"
|
||||
#include "coresight-byte-cntr.h"
|
||||
#include "coresight-common.h"
|
||||
|
||||
#define CSR_BYTECNTVAL (0x06C)
|
||||
|
||||
static void tmc_etr_read_bytes(struct byte_cntr *byte_cntr_data, loff_t *ppos,
|
||||
size_t bytes, size_t *len, char **bufp)
|
||||
{
|
||||
struct tmc_drvdata *tmcdrvdata = byte_cntr_data->tmcdrvdata;
|
||||
struct etr_buf *etr_buf = tmcdrvdata->sysfs_buf;
|
||||
size_t actual;
|
||||
|
||||
if (*len >= bytes)
|
||||
*len = bytes;
|
||||
else if (((uint32_t)*ppos % bytes) + *len > bytes)
|
||||
*len = bytes - ((uint32_t)*ppos % bytes);
|
||||
|
||||
actual = tmc_etr_buf_get_data(etr_buf, *ppos, *len, bufp);
|
||||
*len = actual;
|
||||
if (actual == bytes || (actual + (uint32_t)*ppos) % bytes == 0)
|
||||
atomic_dec(&byte_cntr_data->irq_cnt);
|
||||
}
|
||||
|
||||
|
||||
static irqreturn_t etr_handler(int irq, void *data)
|
||||
{
|
||||
struct byte_cntr *byte_cntr_data = data;
|
||||
|
||||
atomic_inc(&byte_cntr_data->irq_cnt);
|
||||
|
||||
wake_up(&byte_cntr_data->wq);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void tmc_etr_flush_bytes(struct byte_cntr *byte_cntr_data, loff_t *ppos,
|
||||
size_t bytes, size_t *len)
|
||||
{
|
||||
uint32_t rwp = 0;
|
||||
struct tmc_drvdata *tmcdrvdata = byte_cntr_data->tmcdrvdata;
|
||||
dma_addr_t paddr = tmcdrvdata->sysfs_buf->hwaddr;
|
||||
|
||||
rwp = readl_relaxed(tmcdrvdata->base + TMC_RWP);
|
||||
|
||||
if (rwp >= (paddr + *ppos)) {
|
||||
if (bytes > (rwp - paddr - *ppos))
|
||||
*len = rwp - paddr - *ppos;
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t tmc_etr_byte_cntr_read(struct file *fp, char __user *data,
|
||||
size_t len, loff_t *ppos)
|
||||
{
|
||||
struct byte_cntr *byte_cntr_data = fp->private_data;
|
||||
struct tmc_drvdata *tmcdrvdata = byte_cntr_data->tmcdrvdata;
|
||||
char *bufp;
|
||||
int ret = 0;
|
||||
|
||||
if (!data)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&byte_cntr_data->byte_cntr_lock);
|
||||
if (!byte_cntr_data->read_active) {
|
||||
ret = -EINVAL;
|
||||
goto err0;
|
||||
}
|
||||
|
||||
if (byte_cntr_data->enable) {
|
||||
if (!atomic_read(&byte_cntr_data->irq_cnt)) {
|
||||
mutex_unlock(&byte_cntr_data->byte_cntr_lock);
|
||||
if (wait_event_interruptible(byte_cntr_data->wq,
|
||||
atomic_read(&byte_cntr_data->irq_cnt) > 0
|
||||
|| !byte_cntr_data->enable))
|
||||
return -ERESTARTSYS;
|
||||
mutex_lock(&byte_cntr_data->byte_cntr_lock);
|
||||
if (!byte_cntr_data->read_active) {
|
||||
ret = -EINVAL;
|
||||
goto err0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
tmc_etr_read_bytes(byte_cntr_data, ppos,
|
||||
byte_cntr_data->block_size, &len, &bufp);
|
||||
|
||||
} else {
|
||||
if (!atomic_read(&byte_cntr_data->irq_cnt)) {
|
||||
tmc_etr_flush_bytes(byte_cntr_data, ppos, byte_cntr_data->block_size,
|
||||
&len);
|
||||
if (!len) {
|
||||
ret = -EINVAL;
|
||||
goto err0;
|
||||
}
|
||||
} else {
|
||||
tmc_etr_read_bytes(byte_cntr_data, ppos,
|
||||
byte_cntr_data->block_size,
|
||||
&len, &bufp);
|
||||
}
|
||||
}
|
||||
|
||||
if (copy_to_user(data, bufp, len)) {
|
||||
mutex_unlock(&byte_cntr_data->byte_cntr_lock);
|
||||
dev_dbg(&tmcdrvdata->csdev->dev,
|
||||
"%s: copy_to_user failed\n", __func__);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (*ppos + len >= tmcdrvdata->size)
|
||||
*ppos = 0;
|
||||
else
|
||||
*ppos += len;
|
||||
|
||||
goto out;
|
||||
|
||||
err0:
|
||||
mutex_unlock(&byte_cntr_data->byte_cntr_lock);
|
||||
return ret;
|
||||
out:
|
||||
mutex_unlock(&byte_cntr_data->byte_cntr_lock);
|
||||
return len;
|
||||
}
|
||||
|
||||
void tmc_etr_byte_cntr_start(struct byte_cntr *byte_cntr_data)
|
||||
{
|
||||
if (!byte_cntr_data)
|
||||
return;
|
||||
|
||||
mutex_lock(&byte_cntr_data->byte_cntr_lock);
|
||||
|
||||
if (byte_cntr_data->block_size == 0
|
||||
|| byte_cntr_data->read_active) {
|
||||
mutex_unlock(&byte_cntr_data->byte_cntr_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
atomic_set(&byte_cntr_data->irq_cnt, 0);
|
||||
byte_cntr_data->enable = true;
|
||||
mutex_unlock(&byte_cntr_data->byte_cntr_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(tmc_etr_byte_cntr_start);
|
||||
|
||||
void tmc_etr_byte_cntr_stop(struct byte_cntr *byte_cntr_data)
|
||||
{
|
||||
if (!byte_cntr_data)
|
||||
return;
|
||||
|
||||
mutex_lock(&byte_cntr_data->byte_cntr_lock);
|
||||
byte_cntr_data->enable = false;
|
||||
byte_cntr_data->read_active = false;
|
||||
atomic_set(&byte_cntr_data->irq_cnt, 0);
|
||||
wake_up(&byte_cntr_data->wq);
|
||||
coresight_csr_set_byte_cntr(byte_cntr_data->csr,
|
||||
byte_cntr_data->irqctrl_offset, 0);
|
||||
mutex_unlock(&byte_cntr_data->byte_cntr_lock);
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(tmc_etr_byte_cntr_stop);
|
||||
|
||||
|
||||
static int tmc_etr_byte_cntr_release(struct inode *in, struct file *fp)
|
||||
{
|
||||
struct byte_cntr *byte_cntr_data = fp->private_data;
|
||||
|
||||
mutex_lock(&byte_cntr_data->byte_cntr_lock);
|
||||
byte_cntr_data->read_active = false;
|
||||
|
||||
atomic_set(&byte_cntr_data->irq_cnt, 0);
|
||||
coresight_csr_set_byte_cntr(byte_cntr_data->csr,
|
||||
byte_cntr_data->irqctrl_offset, 0);
|
||||
mutex_unlock(&byte_cntr_data->byte_cntr_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tmc_etr_byte_cntr_open(struct inode *in, struct file *fp)
|
||||
{
|
||||
struct byte_cntr *byte_cntr_data =
|
||||
container_of(in->i_cdev, struct byte_cntr, dev);
|
||||
struct tmc_drvdata *tmcdrvdata = byte_cntr_data->tmcdrvdata;
|
||||
|
||||
mutex_lock(&byte_cntr_data->byte_cntr_lock);
|
||||
|
||||
if (tmcdrvdata->mode != CS_MODE_SYSFS ||
|
||||
!byte_cntr_data->block_size) {
|
||||
mutex_unlock(&byte_cntr_data->byte_cntr_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* IRQ is a '8- byte' counter and to observe interrupt at
|
||||
* 'block_size' bytes of data
|
||||
*/
|
||||
|
||||
coresight_csr_set_byte_cntr(byte_cntr_data->csr, byte_cntr_data->irqctrl_offset,
|
||||
(byte_cntr_data->block_size) / 8);
|
||||
|
||||
fp->private_data = byte_cntr_data;
|
||||
nonseekable_open(in, fp);
|
||||
byte_cntr_data->enable = true;
|
||||
byte_cntr_data->read_active = true;
|
||||
mutex_unlock(&byte_cntr_data->byte_cntr_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct file_operations byte_cntr_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = tmc_etr_byte_cntr_open,
|
||||
.read = tmc_etr_byte_cntr_read,
|
||||
.release = tmc_etr_byte_cntr_release,
|
||||
.llseek = no_llseek,
|
||||
};
|
||||
|
||||
static int byte_cntr_register_chardev(struct byte_cntr *byte_cntr_data)
|
||||
{
|
||||
int ret;
|
||||
unsigned int baseminor = 0;
|
||||
unsigned int count = 1;
|
||||
struct device *device;
|
||||
dev_t dev;
|
||||
|
||||
ret = alloc_chrdev_region(&dev, baseminor, count, byte_cntr_data->name);
|
||||
if (ret < 0) {
|
||||
pr_err("alloc_chrdev_region failed %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
cdev_init(&byte_cntr_data->dev, &byte_cntr_fops);
|
||||
|
||||
byte_cntr_data->dev.owner = THIS_MODULE;
|
||||
byte_cntr_data->dev.ops = &byte_cntr_fops;
|
||||
|
||||
ret = cdev_add(&byte_cntr_data->dev, dev, 1);
|
||||
if (ret)
|
||||
goto exit_unreg_chrdev_region;
|
||||
|
||||
byte_cntr_data->driver_class = class_create(THIS_MODULE,
|
||||
byte_cntr_data->class_name);
|
||||
if (IS_ERR(byte_cntr_data->driver_class)) {
|
||||
ret = -ENOMEM;
|
||||
pr_err("class_create failed %d\n", ret);
|
||||
goto exit_unreg_chrdev_region;
|
||||
}
|
||||
|
||||
device = device_create(byte_cntr_data->driver_class, NULL,
|
||||
byte_cntr_data->dev.dev, byte_cntr_data,
|
||||
byte_cntr_data->name);
|
||||
|
||||
if (IS_ERR(device)) {
|
||||
pr_err("class_device_create failed %d\n", ret);
|
||||
ret = -ENOMEM;
|
||||
goto exit_destroy_class;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
exit_destroy_class:
|
||||
class_destroy(byte_cntr_data->driver_class);
|
||||
exit_unreg_chrdev_region:
|
||||
unregister_chrdev_region(byte_cntr_data->dev.dev, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct byte_cntr *byte_cntr_init(struct amba_device *adev,
|
||||
struct tmc_drvdata *drvdata)
|
||||
{
|
||||
struct device *dev = &adev->dev;
|
||||
struct device_node *np = adev->dev.of_node;
|
||||
int byte_cntr_irq;
|
||||
int ret;
|
||||
struct byte_cntr *byte_cntr_data;
|
||||
|
||||
byte_cntr_irq = of_irq_get_byname(np, "byte-cntr-irq");
|
||||
if (byte_cntr_irq < 0)
|
||||
return NULL;
|
||||
|
||||
byte_cntr_data = devm_kzalloc(dev, sizeof(*byte_cntr_data), GFP_KERNEL);
|
||||
if (!byte_cntr_data)
|
||||
return NULL;
|
||||
|
||||
ret = devm_request_irq(dev, byte_cntr_irq, etr_handler,
|
||||
IRQF_TRIGGER_RISING | IRQF_SHARED,
|
||||
dev_name(dev), byte_cntr_data);
|
||||
if (ret) {
|
||||
dev_err(dev, "Byte_cntr interrupt registration failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(dev->of_node, "csr-irqctrl-offset",
|
||||
&byte_cntr_data->irqctrl_offset);
|
||||
|
||||
if (ret) {
|
||||
dev_dbg(dev, "Get byte cntr csr irqctrl offset failed\n");
|
||||
byte_cntr_data->irqctrl_offset = CSR_BYTECNTVAL;
|
||||
}
|
||||
|
||||
ret = device_property_read_string(dev, "byte-cntr-name", &byte_cntr_data->name);
|
||||
if (ret) {
|
||||
dev_dbg(dev, "Get byte cntr name failed\n");
|
||||
byte_cntr_data->name = "byte-cntr";
|
||||
}
|
||||
|
||||
ret = device_property_read_string(dev, "byte-cntr-class-name",
|
||||
&byte_cntr_data->class_name);
|
||||
if (ret) {
|
||||
dev_dbg(dev, "Get byte cntr class name failed\n");
|
||||
byte_cntr_data->class_name = "coresight-tmc-etr-stream";
|
||||
}
|
||||
|
||||
ret = byte_cntr_register_chardev(byte_cntr_data);
|
||||
if (ret) {
|
||||
dev_err(dev, "Byte_cntr char dev registration failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
byte_cntr_data->byte_cntr_irq = byte_cntr_irq;
|
||||
byte_cntr_data->csr = drvdata->csr;
|
||||
byte_cntr_data->tmcdrvdata = drvdata;
|
||||
atomic_set(&byte_cntr_data->irq_cnt, 0);
|
||||
init_waitqueue_head(&byte_cntr_data->wq);
|
||||
mutex_init(&byte_cntr_data->byte_cntr_lock);
|
||||
|
||||
return byte_cntr_data;
|
||||
}
|
||||
|
||||
void byte_cntr_remove(struct byte_cntr *byte_cntr_data)
|
||||
{
|
||||
device_destroy(byte_cntr_data->driver_class,
|
||||
byte_cntr_data->dev.dev);
|
||||
class_destroy(byte_cntr_data->driver_class);
|
||||
unregister_chrdev_region(byte_cntr_data->dev.dev, 1);
|
||||
}
|
||||
35
drivers/hwtracing/coresight/coresight-byte-cntr.h
Normal file
35
drivers/hwtracing/coresight/coresight-byte-cntr.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CORESIGHT_BYTE_CNTR_H
|
||||
#define _CORESIGHT_BYTE_CNTR_H
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/amba/bus.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/mutex.h>
|
||||
#include "coresight-tmc.h"
|
||||
|
||||
struct byte_cntr {
|
||||
struct cdev dev;
|
||||
struct class *driver_class;
|
||||
bool enable;
|
||||
bool read_active;
|
||||
uint32_t byte_cntr_value;
|
||||
uint32_t block_size;
|
||||
int byte_cntr_irq;
|
||||
atomic_t irq_cnt;
|
||||
wait_queue_head_t wq;
|
||||
struct mutex byte_cntr_lock;
|
||||
struct coresight_csr *csr;
|
||||
struct tmc_drvdata *tmcdrvdata;
|
||||
const char *name;
|
||||
const char *class_name;
|
||||
int irqctrl_offset;
|
||||
};
|
||||
|
||||
extern void tmc_etr_byte_cntr_start(struct byte_cntr *byte_cntr_data);
|
||||
extern void tmc_etr_byte_cntr_stop(struct byte_cntr *byte_cntr_data);
|
||||
|
||||
#endif
|
||||
|
|
@ -348,9 +348,51 @@ static ssize_t buffer_size_store(struct device *dev,
|
|||
|
||||
static DEVICE_ATTR_RW(buffer_size);
|
||||
|
||||
static ssize_t block_size_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent);
|
||||
uint32_t val = 0;
|
||||
|
||||
if (drvdata->byte_cntr)
|
||||
val = drvdata->byte_cntr->block_size;
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n",
|
||||
val);
|
||||
}
|
||||
|
||||
static ssize_t block_size_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf,
|
||||
size_t size)
|
||||
{
|
||||
struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent);
|
||||
unsigned long val;
|
||||
|
||||
if (kstrtoul(buf, 0, &val))
|
||||
return -EINVAL;
|
||||
|
||||
if (!drvdata->byte_cntr)
|
||||
return -EINVAL;
|
||||
|
||||
if (val && val < 4096) {
|
||||
pr_err("Assign minimum block size of 4096 bytes\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&drvdata->byte_cntr->byte_cntr_lock);
|
||||
drvdata->byte_cntr->block_size = val;
|
||||
mutex_unlock(&drvdata->byte_cntr->byte_cntr_lock);
|
||||
|
||||
return size;
|
||||
}
|
||||
static DEVICE_ATTR_RW(block_size);
|
||||
|
||||
static struct attribute *coresight_tmc_attrs[] = {
|
||||
&dev_attr_trigger_cntr.attr,
|
||||
&dev_attr_buffer_size.attr,
|
||||
&dev_attr_block_size.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
|
@ -528,6 +570,9 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
|
|||
if (!of_property_read_u32(dev->of_node, "csr-atid-offset",
|
||||
&drvdata->atid_offset))
|
||||
coresight_set_csr_ops(&csr_atid_ops);
|
||||
|
||||
drvdata->byte_cntr = byte_cntr_init(adev, drvdata);
|
||||
|
||||
break;
|
||||
case TMC_CONFIG_TYPE_ETF:
|
||||
desc.type = CORESIGHT_DEV_TYPE_LINKSINK;
|
||||
|
|
@ -606,6 +651,10 @@ static void tmc_remove(struct amba_device *adev)
|
|||
* handler to this device is closed.
|
||||
*/
|
||||
|
||||
if (drvdata->config_type == TMC_CONFIG_TYPE_ETR
|
||||
&& drvdata->byte_cntr)
|
||||
byte_cntr_remove(drvdata->byte_cntr);
|
||||
|
||||
coresight_remove_csr_ops();
|
||||
misc_deregister(&drvdata->miscdev);
|
||||
coresight_unregister(drvdata->csdev);
|
||||
|
|
|
|||
|
|
@ -938,7 +938,7 @@ static void tmc_free_etr_buf(struct etr_buf *etr_buf)
|
|||
* Returns: The size of the linear data available @pos, with *bufpp
|
||||
* updated to point to the buffer.
|
||||
*/
|
||||
static ssize_t tmc_etr_buf_get_data(struct etr_buf *etr_buf,
|
||||
ssize_t tmc_etr_buf_get_data(struct etr_buf *etr_buf,
|
||||
u64 offset, size_t len, char **bufpp)
|
||||
{
|
||||
/* Adjust the length to limit this transaction to end of buffer */
|
||||
|
|
@ -1235,8 +1235,10 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
|
|||
if (free_buf)
|
||||
tmc_etr_free_sysfs_buf(free_buf);
|
||||
|
||||
if (!ret)
|
||||
if (!ret) {
|
||||
tmc_etr_byte_cntr_start(drvdata->byte_cntr);
|
||||
dev_dbg(&csdev->dev, "TMC-ETR enabled\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1706,6 +1708,7 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev)
|
|||
drvdata->perf_buf = NULL;
|
||||
|
||||
spin_unlock_irqrestore(&drvdata->spinlock, flags);
|
||||
tmc_etr_byte_cntr_stop(drvdata->byte_cntr);
|
||||
|
||||
dev_dbg(&csdev->dev, "TMC-ETR disabled\n");
|
||||
return 0;
|
||||
|
|
@ -1748,6 +1751,11 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (drvdata->byte_cntr && drvdata->byte_cntr->enable) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Disable the TMC if we are trying to read from a running session. */
|
||||
if (drvdata->mode == CS_MODE_SYSFS)
|
||||
__tmc_etr_disable_hw(drvdata);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/mutex.h>
|
||||
#include <linux/refcount.h>
|
||||
#include "coresight-priv.h"
|
||||
#include "coresight-byte-cntr.h"
|
||||
|
||||
#define TMC_RSZ 0x004
|
||||
#define TMC_STS 0x00c
|
||||
|
|
@ -212,6 +213,7 @@ struct tmc_drvdata {
|
|||
struct mutex idr_mutex;
|
||||
struct etr_buf *sysfs_buf;
|
||||
struct etr_buf *perf_buf;
|
||||
struct byte_cntr *byte_cntr;
|
||||
struct coresight_csr *csr;
|
||||
const char *csr_name;
|
||||
u32 atid_offset;
|
||||
|
|
@ -273,10 +275,15 @@ extern const struct coresight_ops tmc_etf_cs_ops;
|
|||
|
||||
ssize_t tmc_etb_get_sysfs_trace(struct tmc_drvdata *drvdata,
|
||||
loff_t pos, size_t len, char **bufpp);
|
||||
ssize_t tmc_etr_buf_get_data(struct etr_buf *etr_buf,
|
||||
u64 offset, size_t len, char **bufpp);
|
||||
/* ETR functions */
|
||||
int tmc_read_prepare_etr(struct tmc_drvdata *drvdata);
|
||||
int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata);
|
||||
void tmc_etr_disable_hw(struct tmc_drvdata *drvdata);
|
||||
struct byte_cntr *byte_cntr_init(struct amba_device *adev,
|
||||
struct tmc_drvdata *drvdata);
|
||||
void byte_cntr_remove(struct byte_cntr *byte_cntr);
|
||||
extern const struct coresight_ops tmc_etr_cs_ops;
|
||||
extern const struct csr_set_atid_op csr_atid_ops;
|
||||
ssize_t tmc_etr_get_sysfs_trace(struct tmc_drvdata *drvdata,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user