mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 12:58:12 -04:00
Merge "coresight-tmc: Re-use ETR buffer across use cases"
This commit is contained in:
commit
d1ec209b2c
6 changed files with 104 additions and 5 deletions
|
|
@ -44,5 +44,11 @@ static inline struct coresight_csr *coresight_csr_get(const char *name)
|
|||
static inline int of_get_coresight_csr_name(struct device_node *node,
|
||||
const char **csr_name){ return -EINVAL; }
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_CORESIGHT_CTI) && IS_ENABLED(CONFIG_OF)
|
||||
extern struct coresight_cti_data *of_get_coresight_cti_data(
|
||||
struct device *dev, struct device_node *node);
|
||||
#else
|
||||
static inline struct coresight_cti_data *of_get_coresight_cti_data(
|
||||
struct device *dev, struct device_node *node) { return NULL; }
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1466,6 +1466,48 @@ static int cti_init_save(struct cti_drvdata *drvdata,
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct coresight_cti_data *of_get_coresight_cti_data(
|
||||
struct device *dev, struct device_node *node)
|
||||
{
|
||||
int i, ret;
|
||||
uint32_t ctis_len;
|
||||
struct device_node *child_node;
|
||||
struct coresight_cti_data *ctidata;
|
||||
|
||||
ctidata = devm_kzalloc(dev, sizeof(*ctidata), GFP_KERNEL);
|
||||
if (!ctidata)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
if (of_get_property(node, "coresight-ctis", &ctis_len))
|
||||
ctidata->nr_ctis = ctis_len/sizeof(uint32_t);
|
||||
else
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
if (ctidata->nr_ctis) {
|
||||
ctidata->names = devm_kzalloc(dev, ctidata->nr_ctis *
|
||||
sizeof(*ctidata->names),
|
||||
GFP_KERNEL);
|
||||
if (!ctidata->names)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
for (i = 0; i < ctidata->nr_ctis; i++) {
|
||||
child_node = of_parse_phandle(node, "coresight-ctis",
|
||||
i);
|
||||
if (!child_node)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
ret = of_property_read_string(child_node,
|
||||
"coresight-name",
|
||||
&ctidata->names[i]);
|
||||
of_node_put(child_node);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
}
|
||||
return ctidata;
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_coresight_cti_data);
|
||||
|
||||
static int cti_probe(struct amba_device *adev, const struct amba_id *id)
|
||||
{
|
||||
int ret;
|
||||
|
|
|
|||
|
|
@ -217,6 +217,12 @@ out:
|
|||
if (!used)
|
||||
kfree(buf);
|
||||
|
||||
if (!ret) {
|
||||
coresight_cti_map_trigin(drvdata->cti_reset, 0, 0);
|
||||
coresight_cti_map_trigout(drvdata->cti_flush, 1, 0);
|
||||
dev_info(&csdev->dev, "TMC-ETB/ETF enabled\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -327,6 +333,8 @@ static int tmc_disable_etf_sink(struct coresight_device *csdev)
|
|||
|
||||
spin_unlock_irqrestore(&drvdata->spinlock, flags);
|
||||
|
||||
coresight_cti_unmap_trigin(drvdata->cti_reset, 0, 0);
|
||||
coresight_cti_unmap_trigout(drvdata->cti_flush, 1, 0);
|
||||
dev_dbg(&csdev->dev, "TMC-ETB/ETF disabled\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1135,6 +1135,7 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
|
|||
* buffer, provided the size matches. Any allocation has to be done
|
||||
* with the lock released.
|
||||
*/
|
||||
mutex_lock(&drvdata->mem_lock);
|
||||
spin_lock_irqsave(&drvdata->spinlock, flags);
|
||||
sysfs_buf = READ_ONCE(drvdata->sysfs_buf);
|
||||
if (!sysfs_buf || (sysfs_buf->size != drvdata->size)) {
|
||||
|
|
@ -1142,13 +1143,17 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
|
|||
|
||||
/* Allocate memory with the locks released */
|
||||
free_buf = new_buf = tmc_etr_setup_sysfs_buf(drvdata);
|
||||
if (IS_ERR(new_buf))
|
||||
if (IS_ERR(new_buf)) {
|
||||
mutex_unlock(&drvdata->mem_lock);
|
||||
return PTR_ERR(new_buf);
|
||||
|
||||
}
|
||||
/* Let's try again */
|
||||
spin_lock_irqsave(&drvdata->spinlock, flags);
|
||||
}
|
||||
|
||||
coresight_cti_map_trigout(drvdata->cti_flush, 3, 0);
|
||||
coresight_cti_map_trigin(drvdata->cti_reset, 2, 0);
|
||||
|
||||
if (drvdata->reading || drvdata->mode == CS_MODE_PERF) {
|
||||
ret = -EBUSY;
|
||||
goto out;
|
||||
|
|
@ -1188,6 +1193,7 @@ out:
|
|||
tmc_etr_free_sysfs_buf(free_buf);
|
||||
|
||||
tmc_etr_byte_cntr_start(drvdata->byte_cntr);
|
||||
mutex_unlock(&drvdata->mem_lock);
|
||||
|
||||
if (!ret)
|
||||
dev_dbg(&csdev->dev, "TMC-ETR enabled\n");
|
||||
|
|
@ -1633,10 +1639,12 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev)
|
|||
unsigned long flags;
|
||||
struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
|
||||
|
||||
mutex_lock(&drvdata->mem_lock);
|
||||
spin_lock_irqsave(&drvdata->spinlock, flags);
|
||||
|
||||
if (drvdata->reading) {
|
||||
spin_unlock_irqrestore(&drvdata->spinlock, flags);
|
||||
mutex_unlock(&drvdata->mem_lock);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
|
@ -1657,11 +1665,14 @@ static int tmc_disable_etr_sink(struct coresight_device *csdev)
|
|||
spin_unlock_irqrestore(&drvdata->spinlock, flags);
|
||||
|
||||
tmc_etr_byte_cntr_stop(drvdata->byte_cntr);
|
||||
coresight_cti_unmap_trigin(drvdata->cti_reset, 2, 0);
|
||||
coresight_cti_unmap_trigout(drvdata->cti_flush, 3, 0);
|
||||
/* Free memory outside the spinlock if need be */
|
||||
if (drvdata->etr_buf) {
|
||||
tmc_etr_free_sysfs_buf(drvdata->etr_buf);
|
||||
drvdata->etr_buf = NULL;
|
||||
}
|
||||
mutex_unlock(&drvdata->mem_lock);
|
||||
dev_info(&csdev->dev, "TMC-ETR disabled\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1687,6 +1698,7 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
|
|||
if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&drvdata->mem_lock);
|
||||
spin_lock_irqsave(&drvdata->spinlock, flags);
|
||||
if (drvdata->reading) {
|
||||
ret = -EBUSY;
|
||||
|
|
@ -1715,6 +1727,7 @@ int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
|
|||
drvdata->reading = true;
|
||||
out:
|
||||
spin_unlock_irqrestore(&drvdata->spinlock, flags);
|
||||
mutex_unlock(&drvdata->mem_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1727,7 +1740,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata)
|
|||
/* config types are set a boot time and never change */
|
||||
if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&drvdata->mem_lock);
|
||||
spin_lock_irqsave(&drvdata->spinlock, flags);
|
||||
|
||||
/* RE-enable the TMC if need be */
|
||||
|
|
@ -1754,5 +1767,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata)
|
|||
if (sysfs_buf)
|
||||
tmc_etr_free_sysfs_buf(sysfs_buf);
|
||||
|
||||
|
||||
mutex_unlock(&drvdata->mem_lock);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -184,19 +184,24 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
|
|||
ssize_t actual;
|
||||
struct tmc_drvdata *drvdata = container_of(file->private_data,
|
||||
struct tmc_drvdata, miscdev);
|
||||
mutex_lock(&drvdata->mem_lock);
|
||||
actual = tmc_get_sysfs_trace(drvdata, *ppos, len, &bufp);
|
||||
if (actual <= 0)
|
||||
if (actual <= 0) {
|
||||
mutex_unlock(&drvdata->mem_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (copy_to_user(data, bufp, actual)) {
|
||||
dev_dbg(&drvdata->csdev->dev,
|
||||
"%s: copy_to_user failed\n", __func__);
|
||||
mutex_unlock(&drvdata->mem_lock);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
*ppos += actual;
|
||||
dev_dbg(&drvdata->csdev->dev, "%zu bytes copied\n", actual);
|
||||
|
||||
mutex_unlock(&drvdata->mem_lock);
|
||||
return actual;
|
||||
}
|
||||
|
||||
|
|
@ -493,6 +498,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
|
|||
struct resource *res = &adev->res;
|
||||
struct coresight_desc desc = { 0 };
|
||||
struct coresight_dev_list *dev_list = NULL;
|
||||
struct coresight_cti_data *ctidata;
|
||||
|
||||
ret = -ENOMEM;
|
||||
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
|
||||
|
|
@ -511,6 +517,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
|
|||
drvdata->base = base;
|
||||
|
||||
spin_lock_init(&drvdata->spinlock);
|
||||
mutex_init(&drvdata->mem_lock);
|
||||
|
||||
devid = readl_relaxed(drvdata->base + CORESIGHT_DEVID);
|
||||
drvdata->config_type = BMVAL(devid, 6, 7);
|
||||
|
|
@ -534,6 +541,23 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
|
|||
}
|
||||
}
|
||||
|
||||
ctidata = of_get_coresight_cti_data(dev, adev->dev.of_node);
|
||||
if (IS_ERR(ctidata)) {
|
||||
dev_err(dev, "invalid cti data\n");
|
||||
} else if (ctidata && ctidata->nr_ctis == 2) {
|
||||
drvdata->cti_flush = coresight_cti_get(ctidata->names[0]);
|
||||
if (IS_ERR(drvdata->cti_flush)) {
|
||||
dev_err(dev, "failed to get flush cti, defer probe\n");
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
drvdata->cti_reset = coresight_cti_get(ctidata->names[1]);
|
||||
if (IS_ERR(drvdata->cti_reset)) {
|
||||
dev_err(dev, "failed to get reset cti, defer probe\n");
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
}
|
||||
|
||||
desc.dev = dev;
|
||||
desc.groups = coresight_tmc_groups;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include <linux/miscdevice.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/refcount.h>
|
||||
#include <linux/coresight-cti.h>
|
||||
|
||||
#include "coresight-byte-cntr.h"
|
||||
|
||||
|
|
@ -203,6 +204,7 @@ struct tmc_drvdata {
|
|||
u32 mode;
|
||||
enum tmc_config_type config_type;
|
||||
enum tmc_mem_intf_width memwidth;
|
||||
struct mutex mem_lock;
|
||||
u32 trigger_cntr;
|
||||
u32 etr_caps;
|
||||
struct idr idr;
|
||||
|
|
@ -213,6 +215,8 @@ struct tmc_drvdata {
|
|||
const char *csr_name;
|
||||
bool enable;
|
||||
struct byte_cntr *byte_cntr;
|
||||
struct coresight_cti *cti_flush;
|
||||
struct coresight_cti *cti_reset;
|
||||
};
|
||||
|
||||
struct etr_buf_operations {
|
||||
|
|
|
|||
Loading…
Reference in a new issue