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"
|
||||
|
||||
static DEFINE_MUTEX(coresight_mutex);
|
||||
static struct coresight_device *curr_sink;
|
||||
|
||||
static int coresight_id_match(struct device *dev, void *data)
|
||||
{
|
||||
|
@ -382,6 +383,107 @@ out:
|
|||
}
|
||||
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,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
|
@ -403,12 +505,9 @@ static ssize_t curr_sink_store(struct device *dev,
|
|||
return ret;
|
||||
|
||||
if (val)
|
||||
csdev->activated = true;
|
||||
else
|
||||
csdev->activated = false;
|
||||
coresight_switch_sink(csdev);
|
||||
|
||||
return size;
|
||||
|
||||
}
|
||||
static DEVICE_ATTR_RW(curr_sink);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue