coresight: etb10: adding operation mode for sink->enable()
Adding an operation mode to the sink->enable() API in order to prevent simultaneous access from different callers. TPIU and TMC won't be supplemented with the AUX area API immediately and as such ignore the new mode. Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
27b10da8ff
Коммит
e827d4550a
|
@ -73,9 +73,9 @@
|
|||
* @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.
|
||||
* @buffer_depth: size of @buf.
|
||||
* @enable: this ETB is being used.
|
||||
* @trigger_cntr: amount of words to store after a trigger.
|
||||
*/
|
||||
struct etb_drvdata {
|
||||
|
@ -86,9 +86,9 @@ struct etb_drvdata {
|
|||
struct miscdevice miscdev;
|
||||
spinlock_t spinlock;
|
||||
local_t reading;
|
||||
local_t mode;
|
||||
u8 *buf;
|
||||
u32 buffer_depth;
|
||||
bool enable;
|
||||
u32 trigger_cntr;
|
||||
};
|
||||
|
||||
|
@ -133,16 +133,31 @@ static void etb_enable_hw(struct etb_drvdata *drvdata)
|
|||
CS_LOCK(drvdata->base);
|
||||
}
|
||||
|
||||
static int etb_enable(struct coresight_device *csdev)
|
||||
static int etb_enable(struct coresight_device *csdev, u32 mode)
|
||||
{
|
||||
struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
|
||||
u32 val;
|
||||
unsigned long flags;
|
||||
struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
|
||||
|
||||
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;
|
||||
|
||||
/* Nothing to do, the tracer is already enabled. */
|
||||
if (val == CS_MODE_SYSFS)
|
||||
goto out;
|
||||
|
||||
spin_lock_irqsave(&drvdata->spinlock, flags);
|
||||
etb_enable_hw(drvdata);
|
||||
drvdata->enable = true;
|
||||
spin_unlock_irqrestore(&drvdata->spinlock, flags);
|
||||
|
||||
out:
|
||||
dev_info(drvdata->dev, "ETB enabled\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -243,9 +258,10 @@ static void etb_disable(struct coresight_device *csdev)
|
|||
spin_lock_irqsave(&drvdata->spinlock, flags);
|
||||
etb_disable_hw(drvdata);
|
||||
etb_dump_hw(drvdata);
|
||||
drvdata->enable = false;
|
||||
spin_unlock_irqrestore(&drvdata->spinlock, flags);
|
||||
|
||||
local_set(&drvdata->mode, CS_MODE_DISABLED);
|
||||
|
||||
dev_info(drvdata->dev, "ETB disabled\n");
|
||||
}
|
||||
|
||||
|
@ -263,7 +279,7 @@ static void etb_dump(struct etb_drvdata *drvdata)
|
|||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&drvdata->spinlock, flags);
|
||||
if (drvdata->enable) {
|
||||
if (local_read(&drvdata->mode) == CS_MODE_SYSFS) {
|
||||
etb_disable_hw(drvdata);
|
||||
etb_dump_hw(drvdata);
|
||||
etb_enable_hw(drvdata);
|
||||
|
|
|
@ -62,7 +62,7 @@ static inline void CS_UNLOCK(void __iomem *addr)
|
|||
}
|
||||
|
||||
void coresight_disable_path(struct list_head *path);
|
||||
int coresight_enable_path(struct list_head *path);
|
||||
int coresight_enable_path(struct list_head *path, u32 mode);
|
||||
struct coresight_device *coresight_get_sink(struct list_head *path);
|
||||
struct list_head *coresight_build_path(struct coresight_device *csdev);
|
||||
void coresight_release_path(struct list_head *path);
|
||||
|
|
|
@ -265,7 +265,7 @@ static int tmc_enable(struct tmc_drvdata *drvdata, enum tmc_mode mode)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tmc_enable_sink(struct coresight_device *csdev)
|
||||
static int tmc_enable_sink(struct coresight_device *csdev, u32 mode)
|
||||
{
|
||||
struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ static void tpiu_enable_hw(struct tpiu_drvdata *drvdata)
|
|||
CS_LOCK(drvdata->base);
|
||||
}
|
||||
|
||||
static int tpiu_enable(struct coresight_device *csdev)
|
||||
static int tpiu_enable(struct coresight_device *csdev, u32 mode)
|
||||
{
|
||||
struct tpiu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
|
||||
|
||||
|
|
|
@ -121,13 +121,13 @@ static int coresight_find_link_outport(struct coresight_device *csdev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int coresight_enable_sink(struct coresight_device *csdev)
|
||||
static int coresight_enable_sink(struct coresight_device *csdev, u32 mode)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!csdev->enable) {
|
||||
if (sink_ops(csdev)->enable) {
|
||||
ret = sink_ops(csdev)->enable(csdev);
|
||||
ret = sink_ops(csdev)->enable(csdev, mode);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
@ -283,7 +283,7 @@ void coresight_disable_path(struct list_head *path)
|
|||
}
|
||||
}
|
||||
|
||||
int coresight_enable_path(struct list_head *path)
|
||||
int coresight_enable_path(struct list_head *path, u32 mode)
|
||||
{
|
||||
|
||||
int ret = 0;
|
||||
|
@ -296,7 +296,7 @@ int coresight_enable_path(struct list_head *path)
|
|||
switch (csdev->type) {
|
||||
case CORESIGHT_DEV_TYPE_SINK:
|
||||
case CORESIGHT_DEV_TYPE_LINKSINK:
|
||||
ret = coresight_enable_sink(csdev);
|
||||
ret = coresight_enable_sink(csdev, mode);
|
||||
if (ret)
|
||||
goto err;
|
||||
break;
|
||||
|
@ -454,7 +454,7 @@ int coresight_enable(struct coresight_device *csdev)
|
|||
goto out;
|
||||
}
|
||||
|
||||
ret = coresight_enable_path(path);
|
||||
ret = coresight_enable_path(path, CS_MODE_SYSFS);
|
||||
if (ret)
|
||||
goto err_path;
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ struct coresight_device {
|
|||
* @disable: disables the sink.
|
||||
*/
|
||||
struct coresight_ops_sink {
|
||||
int (*enable)(struct coresight_device *csdev);
|
||||
int (*enable)(struct coresight_device *csdev, u32 mode);
|
||||
void (*disable)(struct coresight_device *csdev);
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче