aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2017-05-15 11:23:10 +1000
committerStephen Rothwell <sfr@canb.auug.org.au>2017-05-15 11:23:10 +1000
commit87d8ed6c188c8f9992854db04e68929bb4b63ed5 (patch)
treef1d153965b4f45809d8b15a22546bb781e8673db
parent6b540b7d4cff01da8855e73fd0175268aa9f6904 (diff)
parent8b3fa19142e84c4fd6a6dc8b348506d5c559a46b (diff)
Merge remote-tracking branch 'coresight/next'
-rw-r--r--drivers/hwtracing/coresight/coresight-etm-perf.c3
-rw-r--r--drivers/hwtracing/coresight/coresight-tmc-etf.c25
-rw-r--r--drivers/hwtracing/coresight/coresight.c34
3 files changed, 44 insertions, 18 deletions
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index 288a423c1b27..8f546f59a3fd 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -201,6 +201,7 @@ static void *etm_setup_aux(int event_cpu, void **pages,
event_data = alloc_event_data(event_cpu);
if (!event_data)
return NULL;
+ INIT_WORK(&event_data->work, free_event_data);
/*
* In theory nothing prevent tracers in a trace session from being
@@ -217,8 +218,6 @@ static void *etm_setup_aux(int event_cpu, void **pages,
if (!sink)
goto err;
- INIT_WORK(&event_data->work, free_event_data);
-
mask = &event_data->mask;
/* Setup the path for each CPU in a trace session */
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
index aec61a6d5c63..e3b9fb82eb8d 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
@@ -166,9 +166,6 @@ out:
if (!used)
kfree(buf);
- if (!ret)
- dev_info(drvdata->dev, "TMC-ETB/ETF enabled\n");
-
return ret;
}
@@ -204,15 +201,27 @@ out:
static int tmc_enable_etf_sink(struct coresight_device *csdev, u32 mode)
{
+ int ret;
+ struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
switch (mode) {
case CS_MODE_SYSFS:
- return tmc_enable_etf_sink_sysfs(csdev);
+ ret = tmc_enable_etf_sink_sysfs(csdev);
+ break;
case CS_MODE_PERF:
- return tmc_enable_etf_sink_perf(csdev);
+ ret = tmc_enable_etf_sink_perf(csdev);
+ break;
+ /* We shouldn't be here */
+ default:
+ ret = -EINVAL;
+ break;
}
- /* We shouldn't be here */
- return -EINVAL;
+ if (ret)
+ return ret;
+
+ dev_info(drvdata->dev, "TMC-ETB/ETF enabled\n");
+ return 0;
}
static void tmc_disable_etf_sink(struct coresight_device *csdev)
@@ -273,7 +282,7 @@ static void tmc_disable_etf_link(struct coresight_device *csdev,
drvdata->mode = CS_MODE_DISABLED;
spin_unlock_irqrestore(&drvdata->spinlock, flags);
- dev_info(drvdata->dev, "TMC disabled\n");
+ dev_info(drvdata->dev, "TMC-ETF disabled\n");
}
static void *tmc_alloc_etf_buffer(struct coresight_device *csdev, int cpu,
diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c
index 0c37356e417c..6a0202b7384f 100644
--- a/drivers/hwtracing/coresight/coresight.c
+++ b/drivers/hwtracing/coresight/coresight.c
@@ -253,14 +253,22 @@ static int coresight_enable_source(struct coresight_device *csdev, u32 mode)
return 0;
}
-static void coresight_disable_source(struct coresight_device *csdev)
+/**
+ * coresight_disable_source - Drop the reference count by 1 and disable
+ * the device if there are no users left.
+ *
+ * @csdev - The coresight device to disable
+ *
+ * Returns true if the device has been disabled.
+ */
+static bool coresight_disable_source(struct coresight_device *csdev)
{
if (atomic_dec_return(csdev->refcnt) == 0) {
- if (source_ops(csdev)->disable) {
+ if (source_ops(csdev)->disable)
source_ops(csdev)->disable(csdev, NULL);
- csdev->enable = false;
- }
+ csdev->enable = false;
}
+ return !csdev->enable;
}
void coresight_disable_path(struct list_head *path)
@@ -550,6 +558,9 @@ int coresight_enable(struct coresight_device *csdev)
int cpu, ret = 0;
struct coresight_device *sink;
struct list_head *path;
+ enum coresight_dev_subtype_source subtype;
+
+ subtype = csdev->subtype.source_subtype;
mutex_lock(&coresight_mutex);
@@ -557,8 +568,16 @@ int coresight_enable(struct coresight_device *csdev)
if (ret)
goto out;
- if (csdev->enable)
+ if (csdev->enable) {
+ /*
+ * There could be multiple applications driving the software
+ * source. So keep the refcount for each such user when the
+ * source is already enabled.
+ */
+ if (subtype == CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE)
+ atomic_inc(csdev->refcnt);
goto out;
+ }
/*
* Search for a valid sink for this session but don't reset the
@@ -585,7 +604,7 @@ int coresight_enable(struct coresight_device *csdev)
if (ret)
goto err_source;
- switch (csdev->subtype.source_subtype) {
+ switch (subtype) {
case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC:
/*
* When working from sysFS it is important to keep track
@@ -629,7 +648,7 @@ void coresight_disable(struct coresight_device *csdev)
if (ret)
goto out;
- if (!csdev->enable)
+ if (!csdev->enable || !coresight_disable_source(csdev))
goto out;
switch (csdev->subtype.source_subtype) {
@@ -647,7 +666,6 @@ void coresight_disable(struct coresight_device *csdev)
break;
}
- coresight_disable_source(csdev);
coresight_disable_path(path);
coresight_release_path(path);