Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d1ec209b authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "coresight-tmc: Re-use ETR buffer across use cases"

parents f16f3bd7 a8928b2c
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -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
+42 −0
Original line number Diff line number Diff line
@@ -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;
+8 −0
Original line number Diff line number Diff line
@@ -217,6 +217,12 @@ static int tmc_enable_etf_sink_sysfs(struct coresight_device *csdev)
	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;
}
+18 −3
Original line number Diff line number Diff line
@@ -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 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
		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;
}
+25 −1
Original line number Diff line number Diff line
@@ -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;

Loading