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

Commit 8f9377dd authored by Mathieu Poirier's avatar Mathieu Poirier Committed by Yabin Cui
Browse files

UPSTREAM: coresight: etb10: Refactor etb_drvdata::mode handling



(Upstream commit d43b8ec599f90c1f07b1bdd29b0c4b6306726ef2).

This patch moves the etb_drvdata::mode from a locat_t to a simple u32,
as it is for the ETF and ETR drivers.  This streamlines the code and adds
commonality with the other drivers when dealing with similar operations.

Signed-off-by: default avatarMathieu Poirier <mathieu.poirier@linaro.org>
Reviewed-by: default avatarSuzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>

Bug: 140266694
Change-Id: I0f38579a632919a0eef37b9825a6cdf23a39b7cd
Signed-off-by: default avatarYabin Cui <yabinc@google.com>
parent 834cb9c8
Loading
Loading
Loading
Loading
+34 −28
Original line number Diff line number Diff line
@@ -5,7 +5,6 @@
 * Description: CoreSight Embedded Trace Buffer driver
 */

#include <asm/local.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/types.h>
@@ -72,8 +71,8 @@
 * @miscdev:	specifics to handle "/dev/xyz.etb" entry.
 * @spinlock:	only one at a time pls.
 * @reading:	synchronise user space access to etb buffer.
 * @mode:	this ETB is being used.
 * @buf:	area of memory where ETB buffer content gets sent.
 * @mode:	this ETB is being used.
 * @buffer_depth: size of @buf.
 * @trigger_cntr: amount of words to store after a trigger.
 */
@@ -85,8 +84,8 @@ struct etb_drvdata {
	struct miscdevice	miscdev;
	spinlock_t		spinlock;
	local_t			reading;
	local_t			mode;
	u8			*buf;
	u32			mode;
	u32			buffer_depth;
	u32			trigger_cntr;
};
@@ -138,44 +137,48 @@ static void etb_enable_hw(struct etb_drvdata *drvdata)
static int etb_enable(struct coresight_device *csdev, u32 mode, void *data)
{
	int ret = 0;
	u32 val;
	unsigned long flags;
	struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);

	/*
	 * We don't have an internal state to clean up if we fail to setup
	 * the perf buffer. So we can perform the step before we turn the
	 * ETB on and leave without cleaning up.
	 */
	if (mode == CS_MODE_PERF) {
		ret = etb_set_buffer(csdev, (struct perf_output_handle *)data);
		if (ret)
			goto out;
	}
	spin_lock_irqsave(&drvdata->spinlock, flags);

	val = local_cmpxchg(&drvdata->mode,
			    CS_MODE_DISABLED, mode);
	/*
	 * When accessing from Perf, a HW buffer can be handled
	 * by a single trace entity.  In sysFS mode many tracers
	 * can be logging to the same HW buffer.
	 */
	if (val == CS_MODE_PERF)
		return -EBUSY;
	if (drvdata->mode == CS_MODE_PERF) {
		ret = -EBUSY;
		goto out;
	}

	/* Don't let perf disturb sysFS sessions */
	if (val == CS_MODE_SYSFS && mode == CS_MODE_PERF)
		return -EBUSY;
	if (drvdata->mode == CS_MODE_SYSFS && mode == CS_MODE_PERF) {
		ret = -EBUSY;
		goto out;
	}

	/* Nothing to do, the tracer is already enabled. */
	if (val == CS_MODE_SYSFS)
	if (drvdata->mode == CS_MODE_SYSFS && mode == CS_MODE_SYSFS)
		goto out;

	spin_lock_irqsave(&drvdata->spinlock, flags);
	/*
	 * We don't have an internal state to clean up if we fail to setup
	 * the perf buffer. So we can perform the step before we turn the
	 * ETB on and leave without cleaning up.
	 */
	if (mode == CS_MODE_PERF) {
		ret = etb_set_buffer(csdev, (struct perf_output_handle *)data);
		if (ret)
			goto out;
	}

	drvdata->mode = mode;
	etb_enable_hw(drvdata);
	spin_unlock_irqrestore(&drvdata->spinlock, flags);

out:
	spin_unlock_irqrestore(&drvdata->spinlock, flags);

	if (!ret)
		dev_dbg(drvdata->dev, "ETB enabled\n");
	return ret;
@@ -277,12 +280,15 @@ static void etb_disable(struct coresight_device *csdev)
	unsigned long flags;

	spin_lock_irqsave(&drvdata->spinlock, flags);

	/* Disable the ETB only if it needs to */
	if (drvdata->mode != CS_MODE_DISABLED) {
		etb_disable_hw(drvdata);
		etb_dump_hw(drvdata);
		drvdata->mode = CS_MODE_DISABLED;
	}
	spin_unlock_irqrestore(&drvdata->spinlock, flags);

	local_set(&drvdata->mode, CS_MODE_DISABLED);

	dev_dbg(drvdata->dev, "ETB disabled\n");
}

@@ -488,7 +494,7 @@ static void etb_dump(struct etb_drvdata *drvdata)
	unsigned long flags;

	spin_lock_irqsave(&drvdata->spinlock, flags);
	if (local_read(&drvdata->mode) == CS_MODE_SYSFS) {
	if (drvdata->mode == CS_MODE_SYSFS) {
		etb_disable_hw(drvdata);
		etb_dump_hw(drvdata);
		etb_enable_hw(drvdata);