diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2017-05-15 11:23:10 +1000 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2017-05-15 11:23:10 +1000 |
commit | 87d8ed6c188c8f9992854db04e68929bb4b63ed5 (patch) | |
tree | f1d153965b4f45809d8b15a22546bb781e8673db | |
parent | 6b540b7d4cff01da8855e73fd0175268aa9f6904 (diff) | |
parent | 8b3fa19142e84c4fd6a6dc8b348506d5c559a46b (diff) |
Merge remote-tracking branch 'coresight/next'
-rw-r--r-- | drivers/hwtracing/coresight/coresight-etm-perf.c | 3 | ||||
-rw-r--r-- | drivers/hwtracing/coresight/coresight-tmc-etf.c | 25 | ||||
-rw-r--r-- | drivers/hwtracing/coresight/coresight.c | 34 |
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); |