coresight: etb10: Refactor etb_drvdata::mode handling
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: Mathieu Poirier <mathieu.poirier@linaro.org> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
		
							parent
							
								
									22f429f19c
								
							
						
					
					
						commit
						d43b8ec599
					
				| @ -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,10 +137,31 @@ 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); | ||||
| 
 | ||||
| 	spin_lock_irqsave(&drvdata->spinlock, flags); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * 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 (drvdata->mode == CS_MODE_PERF) { | ||||
| 		ret = -EBUSY; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Don't let perf disturb sysFS sessions */ | ||||
| 	if (drvdata->mode == CS_MODE_SYSFS && mode == CS_MODE_PERF) { | ||||
| 		ret = -EBUSY; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Nothing to do, the tracer is already enabled. */ | ||||
| 	if (drvdata->mode == CS_MODE_SYSFS && mode == CS_MODE_SYSFS) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * 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 | ||||
| @ -153,29 +173,12 @@ static int etb_enable(struct coresight_device *csdev, u32 mode, void *data) | ||||
| 			goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	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; | ||||
| 
 | ||||
| 	/* Don't let perf disturb sysFS sessions */ | ||||
| 	if (val == CS_MODE_SYSFS && mode == CS_MODE_PERF) | ||||
| 		return -EBUSY; | ||||
| 
 | ||||
| 	/* Nothing to do, the tracer is already enabled. */ | ||||
| 	if (val == CS_MODE_SYSFS) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	spin_lock_irqsave(&drvdata->spinlock, flags); | ||||
| 	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,11 +280,14 @@ static void etb_disable(struct coresight_device *csdev) | ||||
| 	unsigned long flags; | ||||
| 
 | ||||
| 	spin_lock_irqsave(&drvdata->spinlock, flags); | ||||
| 	etb_disable_hw(drvdata); | ||||
| 	etb_dump_hw(drvdata); | ||||
| 	spin_unlock_irqrestore(&drvdata->spinlock, flags); | ||||
| 
 | ||||
| 	local_set(&drvdata->mode, CS_MODE_DISABLED); | ||||
| 	/* 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); | ||||
| 
 | ||||
| 	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); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user