diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/hwtracing/coresight/coresight.c | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c index 7f2b478a048f..3e07fd335f8c 100644 --- a/drivers/hwtracing/coresight/coresight.c +++ b/drivers/hwtracing/coresight/coresight.c @@ -425,6 +425,42 @@ struct coresight_device *coresight_get_enabled_sink(bool deactivate) return dev ? to_coresight_device(dev) : NULL; } +/* + * coresight_grab_device - Power up this device and any of the helper + * devices connected to it for trace operation. Since the helper devices + * don't appear on the trace path, they should be handled along with the + * the master device. + */ +static void coresight_grab_device(struct coresight_device *csdev) +{ + int i; + + for (i = 0; i < csdev->nr_outport; i++) { + struct coresight_device *child = csdev->conns[i].child_dev; + + if (child && child->type == CORESIGHT_DEV_TYPE_HELPER) + pm_runtime_get_sync(child->dev.parent); + } + pm_runtime_get_sync(csdev->dev.parent); +} + +/* + * coresight_drop_device - Release this device and any of the helper + * devices connected to it. + */ +static void coresight_drop_device(struct coresight_device *csdev) +{ + int i; + + pm_runtime_put(csdev->dev.parent); + for (i = 0; i < csdev->nr_outport; i++) { + struct coresight_device *child = csdev->conns[i].child_dev; + + if (child && child->type == CORESIGHT_DEV_TYPE_HELPER) + pm_runtime_put(child->dev.parent); + } +} + /** * _coresight_build_path - recursively build a path from a @csdev to a sink. * @csdev: The device to start from. @@ -473,9 +509,9 @@ out: if (!node) return -ENOMEM; + coresight_grab_device(csdev); node->csdev = csdev; list_add(&node->link, path); - pm_runtime_get_sync(csdev->dev.parent); return 0; } @@ -519,7 +555,7 @@ void coresight_release_path(struct list_head *path) list_for_each_entry_safe(nd, next, path, link) { csdev = nd->csdev; - pm_runtime_put_sync(csdev->dev.parent); + coresight_drop_device(csdev); list_del(&nd->link); kfree(nd); } @@ -770,6 +806,9 @@ static struct device_type coresight_dev_type[] = { .name = "source", .groups = coresight_source_groups, }, + { + .name = "helper", + }, }; static void coresight_device_release(struct device *dev) |