Loading drivers/hwtracing/coresight/coresight.c +56 −45 Original line number Diff line number Diff line Loading @@ -36,18 +36,16 @@ struct coresight_node { }; /* * When operating Coresight drivers from the sysFS interface, only a single * path can exist from a tracer (associated to a CPU) to a sink. * struct coresight_path - path from source to sink * @path: Address of path list. * @link: hook to the list. */ static DEFINE_PER_CPU(struct list_head *, tracer_path); struct coresight_path { struct list_head *path; struct list_head link; }; /* * As of this writing only a single STM can be found in CS topologies. Since * there is no way to know if we'll ever see more and what kind of * configuration they will enact, for the time being only define a single path * for STM. */ static struct list_head *stm_path; static LIST_HEAD(cs_active_paths); /* * When losing synchronisation a new barrier packet needs to be inserted at the Loading Loading @@ -247,7 +245,7 @@ static void coresight_disable_sink(struct coresight_device *csdev) ret = sink_ops(csdev)->disable(csdev); if (ret) return; csdev->enable = false; csdev->activated = false; } static int coresight_enable_link(struct coresight_device *csdev, Loading Loading @@ -484,6 +482,20 @@ int coresight_enable_path(struct list_head *path, u32 mode, void *sink_data) goto out; } static struct coresight_device *coresight_get_source(struct list_head *path) { struct coresight_device *csdev; if (!path) return NULL; csdev = list_first_entry(path, struct coresight_node, link)->csdev; if (csdev->type != CORESIGHT_DEV_TYPE_SOURCE) return NULL; return csdev; } struct coresight_device *coresight_get_sink(struct list_head *path) { struct coresight_device *csdev; Loading Loading @@ -756,9 +768,23 @@ static int coresight_validate_source(struct coresight_device *csdev, return 0; } static int coresight_store_path(struct list_head *path) { struct coresight_path *node; node = kzalloc(sizeof(struct coresight_path), GFP_KERNEL); if (!node) return -ENOMEM; node->path = path; list_add(&node->link, &cs_active_paths); return 0; } int coresight_enable(struct coresight_device *csdev) { int cpu, ret = 0; int ret = 0; struct coresight_device *sink; struct list_head *path; enum coresight_dev_subtype_source subtype; Loading Loading @@ -807,25 +833,9 @@ int coresight_enable(struct coresight_device *csdev) if (ret) goto err_source; switch (subtype) { case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC: /* * When working from sysFS it is important to keep track * of the paths that were created so that they can be * undone in 'coresight_disable()'. Since there can only * be a single session per tracer (when working from sysFS) * a per-cpu variable will do just fine. */ cpu = source_ops(csdev)->cpu_id(csdev); per_cpu(tracer_path, cpu) = path; break; case CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE: stm_path = path; break; default: /* We can't be here */ break; } ret = coresight_store_path(path); if (ret) goto err_source; out: mutex_unlock(&coresight_mutex); Loading @@ -842,8 +852,11 @@ EXPORT_SYMBOL_GPL(coresight_enable); void coresight_disable(struct coresight_device *csdev) { int cpu, ret; int ret; struct list_head *path = NULL; struct coresight_path *cspath = NULL; struct coresight_path *cspath_next = NULL; struct coresight_device *src_csdev = NULL; mutex_lock(&coresight_mutex); Loading @@ -854,20 +867,18 @@ void coresight_disable(struct coresight_device *csdev) if (!csdev->enable || !coresight_disable_source(csdev)) goto out; switch (csdev->subtype.source_subtype) { case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC: cpu = source_ops(csdev)->cpu_id(csdev); path = per_cpu(tracer_path, cpu); per_cpu(tracer_path, cpu) = NULL; break; case CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE: path = stm_path; stm_path = NULL; break; default: /* We can't be here */ break; list_for_each_entry_safe(cspath, cspath_next, &cs_active_paths, link) { src_csdev = coresight_get_source(cspath->path); if (!src_csdev) continue; if (src_csdev == csdev) { path = cspath->path; list_del(&cspath->link); kfree(cspath); } } if (path == NULL) goto out; coresight_disable_path(path); coresight_release_path(path); Loading Loading
drivers/hwtracing/coresight/coresight.c +56 −45 Original line number Diff line number Diff line Loading @@ -36,18 +36,16 @@ struct coresight_node { }; /* * When operating Coresight drivers from the sysFS interface, only a single * path can exist from a tracer (associated to a CPU) to a sink. * struct coresight_path - path from source to sink * @path: Address of path list. * @link: hook to the list. */ static DEFINE_PER_CPU(struct list_head *, tracer_path); struct coresight_path { struct list_head *path; struct list_head link; }; /* * As of this writing only a single STM can be found in CS topologies. Since * there is no way to know if we'll ever see more and what kind of * configuration they will enact, for the time being only define a single path * for STM. */ static struct list_head *stm_path; static LIST_HEAD(cs_active_paths); /* * When losing synchronisation a new barrier packet needs to be inserted at the Loading Loading @@ -247,7 +245,7 @@ static void coresight_disable_sink(struct coresight_device *csdev) ret = sink_ops(csdev)->disable(csdev); if (ret) return; csdev->enable = false; csdev->activated = false; } static int coresight_enable_link(struct coresight_device *csdev, Loading Loading @@ -484,6 +482,20 @@ int coresight_enable_path(struct list_head *path, u32 mode, void *sink_data) goto out; } static struct coresight_device *coresight_get_source(struct list_head *path) { struct coresight_device *csdev; if (!path) return NULL; csdev = list_first_entry(path, struct coresight_node, link)->csdev; if (csdev->type != CORESIGHT_DEV_TYPE_SOURCE) return NULL; return csdev; } struct coresight_device *coresight_get_sink(struct list_head *path) { struct coresight_device *csdev; Loading Loading @@ -756,9 +768,23 @@ static int coresight_validate_source(struct coresight_device *csdev, return 0; } static int coresight_store_path(struct list_head *path) { struct coresight_path *node; node = kzalloc(sizeof(struct coresight_path), GFP_KERNEL); if (!node) return -ENOMEM; node->path = path; list_add(&node->link, &cs_active_paths); return 0; } int coresight_enable(struct coresight_device *csdev) { int cpu, ret = 0; int ret = 0; struct coresight_device *sink; struct list_head *path; enum coresight_dev_subtype_source subtype; Loading Loading @@ -807,25 +833,9 @@ int coresight_enable(struct coresight_device *csdev) if (ret) goto err_source; switch (subtype) { case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC: /* * When working from sysFS it is important to keep track * of the paths that were created so that they can be * undone in 'coresight_disable()'. Since there can only * be a single session per tracer (when working from sysFS) * a per-cpu variable will do just fine. */ cpu = source_ops(csdev)->cpu_id(csdev); per_cpu(tracer_path, cpu) = path; break; case CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE: stm_path = path; break; default: /* We can't be here */ break; } ret = coresight_store_path(path); if (ret) goto err_source; out: mutex_unlock(&coresight_mutex); Loading @@ -842,8 +852,11 @@ EXPORT_SYMBOL_GPL(coresight_enable); void coresight_disable(struct coresight_device *csdev) { int cpu, ret; int ret; struct list_head *path = NULL; struct coresight_path *cspath = NULL; struct coresight_path *cspath_next = NULL; struct coresight_device *src_csdev = NULL; mutex_lock(&coresight_mutex); Loading @@ -854,20 +867,18 @@ void coresight_disable(struct coresight_device *csdev) if (!csdev->enable || !coresight_disable_source(csdev)) goto out; switch (csdev->subtype.source_subtype) { case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC: cpu = source_ops(csdev)->cpu_id(csdev); path = per_cpu(tracer_path, cpu); per_cpu(tracer_path, cpu) = NULL; break; case CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE: path = stm_path; stm_path = NULL; break; default: /* We can't be here */ break; list_for_each_entry_safe(cspath, cspath_next, &cs_active_paths, link) { src_csdev = coresight_get_source(cspath->path); if (!src_csdev) continue; if (src_csdev == csdev) { path = cspath->path; list_del(&cspath->link); kfree(cspath); } } if (path == NULL) goto out; coresight_disable_path(path); coresight_release_path(path); Loading