coresight-tmc: add support to switch sinks
Add support to switch to a different Coresight sink when one or more Coresight tracing sources are enabled. Change-Id: I79f769f0913124710ae56fddea7d205359e09b43 Signed-off-by: Shashank Mittal <mittals@codeaurora.org>
This commit is contained in:
parent
93e852721d
commit
534fd1b6c4
1 changed files with 103 additions and 4 deletions
|
@ -28,6 +28,7 @@
|
||||||
#include "coresight-priv.h"
|
#include "coresight-priv.h"
|
||||||
|
|
||||||
static DEFINE_MUTEX(coresight_mutex);
|
static DEFINE_MUTEX(coresight_mutex);
|
||||||
|
static struct coresight_device *curr_sink;
|
||||||
|
|
||||||
static int coresight_id_match(struct device *dev, void *data)
|
static int coresight_id_match(struct device *dev, void *data)
|
||||||
{
|
{
|
||||||
|
@ -382,6 +383,107 @@ out:
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(coresight_disable);
|
EXPORT_SYMBOL_GPL(coresight_disable);
|
||||||
|
|
||||||
|
static int coresight_disable_all_source(struct device *dev, void *data)
|
||||||
|
{
|
||||||
|
struct coresight_device *csdev;
|
||||||
|
LIST_HEAD(path);
|
||||||
|
|
||||||
|
csdev = to_coresight_device(dev);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No need to care about components that are not sources or not enabled
|
||||||
|
*/
|
||||||
|
if (!csdev->enable || csdev->type != CORESIGHT_DEV_TYPE_SOURCE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
coresight_disable_source(csdev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int coresight_toggle_source_path(struct device *dev, void *data)
|
||||||
|
{
|
||||||
|
struct coresight_device *csdev;
|
||||||
|
bool *enable = data;
|
||||||
|
int ret;
|
||||||
|
LIST_HEAD(path);
|
||||||
|
|
||||||
|
csdev = to_coresight_device(dev);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No need to care about components that are not sources or not enabled
|
||||||
|
*/
|
||||||
|
if (!csdev->enable || csdev->type != CORESIGHT_DEV_TYPE_SOURCE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (*enable) {
|
||||||
|
ret = coresight_build_paths(csdev, &path, true);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(&csdev->dev, "building path(s) failed\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (coresight_build_paths(csdev, &path, false))
|
||||||
|
dev_err(&csdev->dev, "releasing path(s) failed\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int coresight_switch_sink(struct coresight_device *csdev)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
LIST_HEAD(slist);
|
||||||
|
bool enable = false;
|
||||||
|
|
||||||
|
mutex_lock(&coresight_mutex);
|
||||||
|
|
||||||
|
/* If curr_sink is same as new requested sink then do nothing. */
|
||||||
|
if (curr_sink == csdev)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If curr_sink is NULL then sink is getting set for the first time.
|
||||||
|
* No source should be enabled at this time.
|
||||||
|
*/
|
||||||
|
if (!curr_sink) {
|
||||||
|
csdev->activated = true;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* curr_sink is different from csdev */
|
||||||
|
bus_for_each_dev(&coresight_bustype, NULL,
|
||||||
|
&enable, coresight_toggle_source_path);
|
||||||
|
|
||||||
|
csdev->activated = true;
|
||||||
|
curr_sink->activated = false;
|
||||||
|
|
||||||
|
enable = true;
|
||||||
|
ret = bus_for_each_dev(&coresight_bustype, NULL, &enable,
|
||||||
|
coresight_toggle_source_path);
|
||||||
|
if (ret)
|
||||||
|
goto err;
|
||||||
|
out:
|
||||||
|
curr_sink = csdev;
|
||||||
|
mutex_unlock(&coresight_mutex);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
/* Disable sources */
|
||||||
|
bus_for_each_dev(&coresight_bustype, NULL,
|
||||||
|
&enable, coresight_disable_all_source);
|
||||||
|
|
||||||
|
enable = false;
|
||||||
|
bus_for_each_dev(&coresight_bustype, NULL,
|
||||||
|
&enable, coresight_toggle_source_path);
|
||||||
|
|
||||||
|
csdev->activated = false;
|
||||||
|
curr_sink->activated = true;
|
||||||
|
|
||||||
|
mutex_unlock(&coresight_mutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static ssize_t curr_sink_show(struct device *dev,
|
static ssize_t curr_sink_show(struct device *dev,
|
||||||
struct device_attribute *attr, char *buf)
|
struct device_attribute *attr, char *buf)
|
||||||
{
|
{
|
||||||
|
@ -403,12 +505,9 @@ static ssize_t curr_sink_store(struct device *dev,
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (val)
|
if (val)
|
||||||
csdev->activated = true;
|
coresight_switch_sink(csdev);
|
||||||
else
|
|
||||||
csdev->activated = false;
|
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
|
|
||||||
}
|
}
|
||||||
static DEVICE_ATTR_RW(curr_sink);
|
static DEVICE_ATTR_RW(curr_sink);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue