Thread (24 messages) 24 messages, 5 authors, 2014-07-15

[PATCH 1/9 v2] coresight: add CoreSight core layer framework

From: mathieu.poirier@linaro.org (Mathieu Poirier)
Date: 2014-07-02 19:06:48
Also in: lkml

Thanks for the review  - please see my comments inline.

Mathieu

On 2 July 2014 03:38, Daniel Thompson [off-list ref] wrote:
On 27/06/14 19:04, mathieu.poirier at linaro.org wrote:
quoted
diff --git a/drivers/coresight/Kconfig b/drivers/coresight/Kconfig
new file mode 100644
index 0000000..fdd4d08
--- /dev/null
+++ b/drivers/coresight/Kconfig
@@ -0,0 +1,10 @@
+menuconfig CORESIGHT
+     bool "CoreSight Tracing Support"
+     select ARM_AMBA
+     help
+       This framework provides an interface for the CoreSight debug and
+       trace drivers to register themselves with. It's intended to build
+       up a topological view of the CoreSight components and configure
+       the right series of components on user input via sysfs. It also
I don't understand this sentence. It makes is sound like user input is
needed somehow.
That is interesting - I will see if it can be reworked a little.
quoted
diff --git a/drivers/coresight/coresight-priv.h b/drivers/coresight/coresight-priv.h
new file mode 100644
index 0000000..da1ebbb
--- /dev/null
+++ b/drivers/coresight/coresight-priv.h
@@ -0,0 +1,69 @@
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CORESIGHT_PRIV_H
+#define _CORESIGHT_PRIV_H
+
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/coresight.h>
+
+/*
+ * Coresight management registers (0xF00-0xFCC)
+ * 0xFA0 - 0xFA4: Management registers in PFTv1.0
+ *             Trace         registers in PFTv1.1
+ */
+#define CORESIGHT_ITCTRL     (0xF00)
+#define CORESIGHT_CLAIMSET   (0xFA0)
+#define CORESIGHT_CLAIMCLR   (0xFA4)
+#define CORESIGHT_LAR                (0xFB0)
+#define CORESIGHT_LSR                (0xFB4)
+#define CORESIGHT_AUTHSTATUS (0xFB8)
+#define CORESIGHT_DEVID              (0xFC8)
+#define CORESIGHT_DEVTYPE    (0xFCC)
+
+#define TIMEOUT_US           (100)
+
+#define BM(lsb, msb)         ((BIT(msb) - BIT(lsb)) + BIT(msb))
Isn't this what GENMASK() already does?
You seem to be correct - I'll look further into it and will change if need be.
quoted
+#define BMVAL(val, lsb, msb) ((val & BM(lsb, msb)) >> lsb)
+#define BVAL(val, n)         ((val & BIT(n)) >> n)
BVAL() is obfuscation and should be removed.

As an example (taken from one of the patches that consumes this macro):

+       for (i = TIMEOUT_US;
+            BVAL(cs_readl(drvdata->base, ETB_FFCR), ETB_FFCR_BIT) != 0
+            && i > 0; i--)
+               udelay(1);

Is not really as readable as:

+       for (i = TIMEOUT_US;
+            cs_readl(drvdata->base, ETB_FFCR) & ETB_FFCR_BIT && i > 0;
+            i--)
+               udelay(1);

Within the whole patchset it is only every usedIt is only ever used call
site looks more or less like this:
Re-writing those loops is long overdue - ack.
quoted
+#define cs_writel(addr, val, off)    __raw_writel((val), addr + off)
+#define cs_readl(addr, off)          __raw_readl(addr + off)
Out of interest, would readl/writel_relaxed() more appropriate?
Indeed - Linus W. pointed that out for the RFC - I had a patch but it
somehow slipped through.
quoted
+
+static inline void CS_LOCK(void __iomem *addr)
+{
+     do {
+             /* wait for things to settle */
+             mb();
+             cs_writel(addr, 0x0, CORESIGHT_LAR);
+     } while (0);
+}
+
+static inline void CS_UNLOCK(void __iomem *addr)
+{
+     do {
+             cs_writel(addr, CORESIGHT_UNLOCK, CORESIGHT_LAR);
+             /* make sure eveyone has seen this */
+             mb();
+     } while (0);
+}
+
+#ifdef CONFIG_CORESIGHT_SOURCE_ETM
+extern unsigned int etm_readl_cp14(u32 off);
+extern void etm_writel_cp14(u32 val, u32 off);
+#else
+static inline unsigned int etm_readl_cp14(u32 off) { return 0; }
+static inline void etm_writel_cp14(u32 val, u32 off) {}
+#endif
+
+#endif
diff --git a/drivers/coresight/coresight.c b/drivers/coresight/coresight.c
new file mode 100644
index 0000000..6218d86
--- /dev/null
+++ b/drivers/coresight/coresight.c
@@ -0,0 +1,680 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/export.h>
+#include <linux/slab.h>
+#include <linux/semaphore.h>
+#include <linux/clk.h>
+#include <linux/coresight.h>
+#include <linux/of_platform.h>
+#include <linux/debugfs.h>
+
+#include "coresight-priv.h"
+
+#define NO_SINK              (-1)
+
+struct dentry *cs_debugfs_parent = NULL;
+
+static int curr_sink = NO_SINK;
+static LIST_HEAD(coresight_orph_conns);
+static LIST_HEAD(coresight_devs);
+static DEFINE_SEMAPHORE(coresight_mutex);
Why is coresight_mutex a semaphore?
Bad naming convention.
quoted
+static int coresight_find_link_inport(struct coresight_device *csdev)
+{
+     int i;
+     struct coresight_device *parent;
+     struct coresight_connection *conn;
+
+     parent = container_of(csdev->path_link.next, struct coresight_device,
+                          path_link);
+     for (i = 0; i < parent->nr_conns; i++) {
+             conn = &parent->conns[i];
+             if (conn->child_dev == csdev)
+                     return conn->child_port;
+     }
+
+     pr_err("coresight: couldn't find inport, parent: %d, child: %d\n",
+            parent->id, csdev->id);
+     return 0;
+}
+
+static int coresight_find_link_outport(struct coresight_device *csdev)
+{
+     int i;
+     struct coresight_device *child;
+     struct coresight_connection *conn;
+
+     child = container_of(csdev->path_link.prev, struct coresight_device,
+                           path_link);
+     for (i = 0; i < csdev->nr_conns; i++) {
+             conn = &csdev->conns[i];
+             if (conn->child_dev == child)
+                     return conn->outport;
+     }
+
+     pr_err("coresight: couldn't find outport, parent: %d, child: %d\n",
+            csdev->id, child->id);
+     return 0;
+}
+
+static int coresight_enable_sink(struct coresight_device *csdev)
+{
+     int ret;
+
+     if (csdev->refcnt.sink_refcnt == 0) {
+             if (csdev->ops->sink_ops->enable) {
+                     ret = csdev->ops->sink_ops->enable(csdev);
+                     if (ret)
+                             goto err;
+                     csdev->enable = true;
+             }
+     }
+     csdev->refcnt.sink_refcnt++;
+
+     return 0;
+err:
+     return ret;
+}
+
+static void coresight_disable_sink(struct coresight_device *csdev)
+{
+     if (csdev->refcnt.sink_refcnt == 1) {
+             if (csdev->ops->sink_ops->disable) {
+                     csdev->ops->sink_ops->disable(csdev);
+                     csdev->enable = false;
+             }
+     }
+     csdev->refcnt.sink_refcnt--;
+}
+
+static int coresight_enable_link(struct coresight_device *csdev)
+{
+     int ret;
+     int link_subtype;
+     int refport, inport, outport;
+
+     inport = coresight_find_link_inport(csdev);
+     outport = coresight_find_link_outport(csdev);
+
+     link_subtype = csdev->subtype.link_subtype;
+     if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG)
+             refport = inport;
+     else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT)
+             refport = outport;
+     else
+             refport = 0;
+
+     if (csdev->refcnt.link_refcnts[refport] == 0) {
+             if (csdev->ops->link_ops->enable) {
+                     ret = csdev->ops->link_ops->enable(csdev, inport,
+                                                        outport);
+                     if (ret)
+                             goto err;
+                     csdev->enable = true;
+             }
+     }
+     csdev->refcnt.link_refcnts[refport]++;
+
+     return 0;
+err:
+     return ret;
+}
+
+static void coresight_disable_link(struct coresight_device *csdev)
+{
+     int link_subtype;
+     int refport, inport, outport;
+
+     inport = coresight_find_link_inport(csdev);
+     outport = coresight_find_link_outport(csdev);
+
+     link_subtype = csdev->subtype.link_subtype;
+     if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG)
+             refport = inport;
+     else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT)
+             refport = outport;
+     else
+             refport = 0;
I already read these 7 lines once...
It is really worth spinning off a function to save 5 lines?
quoted
+
+     if (csdev->refcnt.link_refcnts[refport] == 1) {
+             if (csdev->ops->link_ops->disable) {
+                     csdev->ops->link_ops->disable(csdev, inport, outport);
+                     csdev->enable = false;
+             }
+     }
+     csdev->refcnt.link_refcnts[refport]--;
+}
+
+static int coresight_enable_source(struct coresight_device *csdev)
+{
+     int ret;
+
+     if (csdev->refcnt.source_refcnt == 0) {
+             if (csdev->ops->source_ops->enable) {
+                     ret = csdev->ops->source_ops->enable(csdev);
+                     if (ret)
+                             goto err;
+                     csdev->enable = true;
+             }
+     }
+     csdev->refcnt.source_refcnt++;
+
+     return 0;
+err:
+     return ret;
+}
+
+static void coresight_disable_source(struct coresight_device *csdev)
+{
+     if (csdev->refcnt.source_refcnt == 1) {
+             if (csdev->ops->source_ops->disable) {
+                     csdev->ops->source_ops->disable(csdev);
+                     csdev->enable = false;
+             }
+     }
+     csdev->refcnt.source_refcnt--;
+}
+
+static struct list_head *coresight_build_path(struct coresight_device *csdev,
+                                           struct list_head *path)
+{
+     int i;
+     struct list_head *p;
+     struct coresight_connection *conn;
+
+     if (csdev->id == curr_sink) {
+             list_add_tail(&csdev->path_link, path);
+             return path;
+     }
+
+     for (i = 0; i < csdev->nr_conns; i++) {
+             conn = &csdev->conns[i];
+             p = coresight_build_path(conn->child_dev, path);
+             if (p) {
+                     list_add_tail(&csdev->path_link, p);
+                     return p;
+             }
+     }
+     return NULL;
+}
+
+static void coresight_release_path(struct list_head *path)
+{
+     struct coresight_device *cd, *temp;
+
+     list_for_each_entry_safe(cd, temp, path, path_link)
+             list_del(&cd->path_link);
+}
+
+static int coresight_enable_path(struct list_head *path, bool incl_source)
+{
+     int ret = 0;
+     struct coresight_device *cd;
+
+     list_for_each_entry(cd, path, path_link) {
+             if (cd == list_first_entry(path, struct coresight_device,
+                                        path_link)) {
+                     ret = coresight_enable_sink(cd);
+             } else if (list_is_last(&cd->path_link, path)) {
+                     if (incl_source)
+                             ret = coresight_enable_source(cd);
+             } else {
+                     ret = coresight_enable_link(cd);
+             }
+             if (ret)
+                     goto err;
+     }
+     return 0;
+err:
+     list_for_each_entry_continue_reverse(cd, path, path_link) {
+             if (cd == list_first_entry(path, struct coresight_device,
+                                        path_link)) {
+                     coresight_disable_sink(cd);
+             } else if (list_is_last(&cd->path_link, path)) {
+                     if (incl_source)
+                             coresight_disable_source(cd);
+             } else {
+                     coresight_disable_link(cd);
+             }
+     }
+     return ret;
+}
+
+static void coresight_disable_path(struct list_head *path, bool incl_source)
+{
+     struct coresight_device *cd;
+
+     list_for_each_entry(cd, path, path_link) {
+             if (cd == list_first_entry(path, struct coresight_device,
+                                        path_link)) {
+                     coresight_disable_sink(cd);
+             } else if (list_is_last(&cd->path_link, path)) {
+                     if (incl_source)
+                             coresight_disable_source(cd);
+             } else {
+                     coresight_disable_link(cd);
+             }
+     }
+}
+
+static int coresight_switch_sink(struct coresight_device *csdev)
+{
+     int ret = 0;
+     LIST_HEAD(path);
+     struct coresight_device *cd;
+
+     if (IS_ERR_OR_NULL(csdev))
+             return -EINVAL;
If we really believe the caller is likely to do something this stupid we
should probably WARN_ON() for their own good.
ack
quoted
+
+     down(&coresight_mutex);
+     if (csdev->id == curr_sink)
+             goto out;
+
+     list_for_each_entry(cd, &coresight_devs, dev_link) {
+             if (cd->type == CORESIGHT_DEV_TYPE_SOURCE && cd->enable) {
+                     coresight_build_path(cd, &path);
+                     coresight_disable_path(&path, false);
+                     coresight_release_path(&path);
+             }
+     }
+     curr_sink = csdev->id;
+     list_for_each_entry(cd, &coresight_devs, dev_link) {
+             if (cd->type == CORESIGHT_DEV_TYPE_SOURCE && cd->enable) {
+                     coresight_build_path(cd, &path);
+                     ret = coresight_enable_path(&path, false);
+                     coresight_release_path(&path);
+                     if (ret)
+                             goto err;
+             }
+     }
+out:
+     up(&coresight_mutex);
+     return 0;
+err:
+     list_for_each_entry(cd, &coresight_devs, dev_link) {
+             if (cd->type == CORESIGHT_DEV_TYPE_SOURCE && cd->enable)
+                     coresight_disable_source(cd);
+     }
+     pr_err("coresight: sink switch failed, sources disabled; try again\n");
coresight_mutex is still locked at this point (so trying again won't
help ;-).

quoted
+     return ret;
+}
+
+int coresight_enable(struct coresight_device *csdev)
+{
+     int ret = 0;
+     LIST_HEAD(path);
+
+     if (IS_ERR_OR_NULL(csdev))
+             return -EINVAL;
WARN_ON() or remove.

quoted
+
+     down(&coresight_mutex);
+     if (csdev->type != CORESIGHT_DEV_TYPE_SOURCE) {
+             ret = -EINVAL;
+             pr_err("coresight: wrong device type in %s\n", __func__);
+             goto out;
+     }
+     if (csdev->enable)
+             goto out;
+
+     coresight_build_path(csdev, &path);
+     ret = coresight_enable_path(&path, true);
+     coresight_release_path(&path);
+     if (ret)
+             pr_err("coresight: enable failed\n");
+out:
+     up(&coresight_mutex);
+     return ret;
+}
+EXPORT_SYMBOL_GPL(coresight_enable);
+
+void coresight_disable(struct coresight_device *csdev)
+{
+     LIST_HEAD(path);
+
+     if (IS_ERR_OR_NULL(csdev))
+             return;
+
+     down(&coresight_mutex);
+     if (csdev->type != CORESIGHT_DEV_TYPE_SOURCE) {
+             pr_err("coresight: wrong device type in %s\n", __func__);
+             goto out;
+     }
+     if (!csdev->enable)
+             goto out;
+
+     coresight_build_path(csdev, &path);
+     coresight_disable_path(&path, true);
+     coresight_release_path(&path);
+out:
+     up(&coresight_mutex);
+}
+EXPORT_SYMBOL_GPL(coresight_disable);
+
+void coresight_abort(void)
+{
+     struct coresight_device *cd;
+
+     if (down_trylock(&coresight_mutex)) {
+             pr_err("coresight: abort could not be processed\n");
+             return;
+     }
+     if (curr_sink == NO_SINK)
+             goto out;
+
+     list_for_each_entry(cd, &coresight_devs, dev_link) {
+             if (cd->id == curr_sink) {
+                     if (cd->enable && cd->ops->sink_ops->abort) {
+                             cd->ops->sink_ops->abort(cd);
+                             cd->enable = false;
+                     }
+             }
+     }
+out:
+     up(&coresight_mutex);
+}
+EXPORT_SYMBOL_GPL(coresight_abort);
+
+static ssize_t debugfs_curr_sink_get(void *data, u64 *val)
+{
+     struct coresight_device *csdev = data;
+
+     *val = (csdev->id == curr_sink) ? 1 : 0;
+     return 0;
+}
+
+static ssize_t debugfs_curr_sink_set(void *data, u64 val)
+{
+     struct coresight_device *csdev = data;
+
+     if (val)
+             return coresight_switch_sink(csdev);
+     else
+             return -EINVAL;
+}
+CORESIGHT_DEBUGFS_ENTRY(debugfs_curr_sink, "curr_sink",
+                     S_IRUGO | S_IWUSR, debugfs_curr_sink_get,
+                     debugfs_curr_sink_set, "%llu\n");
+
+static ssize_t debugfs_enable_get(void *data, u64 *val)
+{
+     struct coresight_device *csdev = data;
+
+     *val = csdev->enable;
+     return 0;
+}
+
+static ssize_t debugfs_enable_set(void *data, u64 val)
+{
+     struct coresight_device *csdev = data;
+
+     if (val)
+             return coresight_enable(csdev);
+     else
+             coresight_disable(csdev);
+
+     return 0;
+}
+CORESIGHT_DEBUGFS_ENTRY(debugfs_enable, "enable",
+                     S_IRUGO | S_IWUSR, debugfs_enable_get,
+                     debugfs_enable_set, "%llu\n");
+
+
+static const struct coresight_ops_entry *coresight_grps_sink[] = {
+     &debugfs_curr_sink_entry,
+     NULL,
+};
+
+static const struct coresight_ops_entry *coresight_grps_source[] = {
+     &debugfs_enable_entry,
+     NULL,
+};
+
+struct coresight_group_entries {
+     const char *name;
+     const struct coresight_ops_entry **entries;
+};
+
+struct coresight_group_entries coresight_debugfs_entries[] = {
+     {
+             .name = "none",
+     },
+     {
+             .name = "sink",
+             .entries = coresight_grps_sink,
+     },
+     {
+             .name = "link",
+     },
+     {
+             .name = "linksink",
+     },
+     {
+             .name = "source",
+             .entries = coresight_grps_source,
+     },
+};
+
+static void coresight_device_release(struct device *dev)
+{
+     struct coresight_device *csdev = to_coresight_device(dev);
+     kfree(csdev);
+}
+
+static void coresight_fixup_orphan_conns(struct coresight_device *csdev)
+{
+     struct coresight_connection *conn, *temp;
+
+     list_for_each_entry_safe(conn, temp, &coresight_orph_conns, link) {
+             if (conn->child_id == csdev->id) {
+                     conn->child_dev = csdev;
+                     list_del(&conn->link);
+             }
+     }
+}
+
+static void coresight_fixup_device_conns(struct coresight_device *csdev)
+{
+     int i;
+     struct coresight_device *cd;
+     bool found;
+
+     for (i = 0; i < csdev->nr_conns; i++) {
+             found = false;
+             list_for_each_entry(cd, &coresight_devs, dev_link) {
+                     if (csdev->conns[i].child_id == cd->id) {
+                             csdev->conns[i].child_dev = cd;
+                             found = true;
+                             break;
+                     }
+             }
+             if (!found)
+                     list_add_tail(&csdev->conns[i].link,
+                                   &coresight_orph_conns);
+     }
+}
+
+static int debugfs_coresight_init(void)
+{
+     if (!cs_debugfs_parent) {
+             cs_debugfs_parent = debugfs_create_dir("coresight", 0);
+             if (IS_ERR(cs_debugfs_parent))
+                     return -1;
+     }
+
+     return 0;
+}
+
+static struct dentry *coresight_debugfs_desc_init(
+                             struct coresight_device *csdev,
+                             const struct coresight_ops_entry **debugfs_ops)
+{
+     int i = 0;
+     struct dentry *parent;
+     struct device *dev = &csdev->dev;
+     const struct coresight_ops_entry *ops_entry, **ops_entries;
+
+     parent = debugfs_create_dir(dev_name(dev), cs_debugfs_parent);
+     if (IS_ERR(parent))
+             return NULL;
+
+     /* device-specific ops */
+     while (debugfs_ops && debugfs_ops[i]) {
+             ops_entry = debugfs_ops[i];
+             if (!debugfs_create_file(ops_entry->name, ops_entry->mode,
+                                      parent, dev_get_drvdata(dev->parent),
+                                      ops_entry->ops)) {
+                     debugfs_remove_recursive(parent);
+                     return NULL;
+             }
+             i++;
+     }
+
+     /* group-specific ops */
+     i = 0;
+     ops_entries = coresight_debugfs_entries[csdev->type].entries;
+
+     while (ops_entries && ops_entries[i]) {
+             if (!debugfs_create_file(ops_entries[i]->name,
+                                      ops_entries[i]->mode,
+                                      parent, csdev, ops_entries[i]->ops)) {
+                     debugfs_remove_recursive(parent);
+                     return NULL;
+             }
+             i++;
+     }
+
+     return parent;
+}
+
+struct coresight_device *coresight_register(struct coresight_desc *desc)
+{
+     int i;
+     int ret;
+     int link_subtype;
+     int nr_refcnts;
+     int *refcnts = NULL;
+     struct coresight_device *csdev;
+     struct coresight_connection *conns;
+
+     if (IS_ERR_OR_NULL(desc))
+             return ERR_PTR(-EINVAL);
+
+     csdev = kzalloc(sizeof(*csdev), GFP_KERNEL);
+     if (!csdev) {
+             ret = -ENOMEM;
+             goto err_kzalloc_csdev;
+     }
+
+     csdev->id = desc->pdata->id;
+
+     if (desc->type == CORESIGHT_DEV_TYPE_LINK ||
+         desc->type == CORESIGHT_DEV_TYPE_LINKSINK) {
+             link_subtype = desc->subtype.link_subtype;
+             if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG)
+                     nr_refcnts = desc->pdata->nr_inports;
+             else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT)
+                     nr_refcnts = desc->pdata->nr_outports;
+             else
+                     nr_refcnts = 1;
+
+             refcnts = kzalloc(sizeof(*refcnts) * nr_refcnts, GFP_KERNEL);
+             if (!refcnts) {
+                     ret = -ENOMEM;
+                     goto err_kzalloc_refcnts;
+             }
+             csdev->refcnt.link_refcnts = refcnts;
+     }
+
+     csdev->nr_conns = desc->pdata->nr_outports;
+     conns = kzalloc(sizeof(*conns) * csdev->nr_conns, GFP_KERNEL);
+     if (!conns) {
+             ret = -ENOMEM;
+             goto err_kzalloc_conns;
+     }
+
+     for (i = 0; i < csdev->nr_conns; i++) {
+             conns[i].outport = desc->pdata->outports[i];
+             conns[i].child_id = desc->pdata->child_ids[i];
+             conns[i].child_port = desc->pdata->child_ports[i];
+     }
+     csdev->conns = conns;
+
+     csdev->type = desc->type;
+     csdev->subtype = desc->subtype;
+     csdev->ops = desc->ops;
+     csdev->owner = desc->owner;
+
+     csdev->dev.parent = desc->dev;
+     csdev->dev.release = coresight_device_release;
+     dev_set_name(&csdev->dev, "%s", desc->pdata->name);
+
+     down(&coresight_mutex);
+     if (desc->pdata->default_sink) {
+             if (curr_sink == NO_SINK) {
+                     curr_sink = csdev->id;
+             } else {
+                     ret = -EINVAL;
+                     goto err_default_sink;
+             }
+     }
+
+     coresight_fixup_device_conns(csdev);
+
+     debugfs_coresight_init();
Return value ignored here.
ack
quoted
+     csdev->de = coresight_debugfs_desc_init(csdev, desc->debugfs_ops);
+
+     coresight_fixup_orphan_conns(csdev);
+
+     list_add_tail(&csdev->dev_link, &coresight_devs);
+     up(&coresight_mutex);
+
+     return csdev;
...
quoted
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
new file mode 100644
index 0000000..a19420e
--- /dev/null
+++ b/include/linux/coresight.h
@@ -0,0 +1,190 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _LINUX_CORESIGHT_H
+#define _LINUX_CORESIGHT_H
+
+#include <linux/device.h>
+
+/* Peripheral id registers (0xFD0-0xFEC) */
+#define CORESIGHT_PERIPHIDR4 (0xFD0)
+#define CORESIGHT_PERIPHIDR5 (0xFD4)
+#define CORESIGHT_PERIPHIDR6 (0xFD8)
+#define CORESIGHT_PERIPHIDR7 (0xFDC)
+#define CORESIGHT_PERIPHIDR0 (0xFE0)
+#define CORESIGHT_PERIPHIDR1 (0xFE4)
+#define CORESIGHT_PERIPHIDR2 (0xFE8)
+#define CORESIGHT_PERIPHIDR3 (0xFEC)
+/* Component id registers (0xFF0-0xFFC) */
+#define CORESIGHT_COMPIDR0   (0xFF0)
+#define CORESIGHT_COMPIDR1   (0xFF4)
+#define CORESIGHT_COMPIDR2   (0xFF8)
+#define CORESIGHT_COMPIDR3   (0xFFC)
+
+#define ETM_ARCH_V3_3                (0x23)
+#define ETM_ARCH_V3_5                (0x25)
+#define PFT_ARCH_V1_1                (0x31)
+
+#define CORESIGHT_UNLOCK     (0xC5ACCE55)
+
+enum coresight_clk_rate {
+     CORESIGHT_CLK_RATE_OFF,
+     CORESIGHT_CLK_RATE_TRACE,
+     CORESIGHT_CLK_RATE_HSTRACE,
+};
+
+enum coresight_dev_type {
+     CORESIGHT_DEV_TYPE_NONE,
+     CORESIGHT_DEV_TYPE_SINK,
+     CORESIGHT_DEV_TYPE_LINK,
+     CORESIGHT_DEV_TYPE_LINKSINK,
+     CORESIGHT_DEV_TYPE_SOURCE,
+};
+
+enum coresight_dev_subtype_sink {
+     CORESIGHT_DEV_SUBTYPE_SINK_NONE,
+     CORESIGHT_DEV_SUBTYPE_SINK_PORT,
+     CORESIGHT_DEV_SUBTYPE_SINK_BUFFER,
+};
+
+enum coresight_dev_subtype_link {
+     CORESIGHT_DEV_SUBTYPE_LINK_NONE,
+     CORESIGHT_DEV_SUBTYPE_LINK_MERG,
+     CORESIGHT_DEV_SUBTYPE_LINK_SPLIT,
+     CORESIGHT_DEV_SUBTYPE_LINK_FIFO,
+};
+
+enum coresight_dev_subtype_source {
+     CORESIGHT_DEV_SUBTYPE_SOURCE_NONE,
+     CORESIGHT_DEV_SUBTYPE_SOURCE_PROC,
+     CORESIGHT_DEV_SUBTYPE_SOURCE_BUS,
+     CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE,
+};
+
+struct coresight_ops_entry {
+     const char *name;
+     umode_t mode;
+     const struct file_operations *ops;
+};
+
+struct coresight_dev_subtype {
+     enum coresight_dev_subtype_sink sink_subtype;
+     enum coresight_dev_subtype_link link_subtype;
+     enum coresight_dev_subtype_source source_subtype;
+};
+
+struct coresight_platform_data {
+     int id;
+     int cpu;
+     const char *name;
+     int nr_inports;
+     const int *outports;
+     const int *child_ids;
+     const int *child_ports;
+     int nr_outports;
+     bool default_sink;
+     struct clk *clk;
+};
+
+struct coresight_desc {
+     enum coresight_dev_type type;
+     struct coresight_dev_subtype subtype;
+     const struct coresight_ops *ops;
+     struct coresight_platform_data *pdata;
+     struct device *dev;
+     const struct coresight_ops_entry **debugfs_ops;
+     struct module *owner;
+};
+
+struct coresight_connection {
+     int outport;
+     int child_id;
+     int child_port;
+     struct coresight_device *child_dev;
+     struct list_head link;
+};
+
+struct coresight_refcnt {
+     int sink_refcnt;
+     int *link_refcnts;
+     int source_refcnt;
+};
+
+struct coresight_device {
+     int id;
+     struct coresight_connection *conns;
+     int nr_conns;
+     enum coresight_dev_type type;
+     struct coresight_dev_subtype subtype;
+     const struct coresight_ops *ops;
+     struct dentry *de;
+     struct device dev;
+     struct coresight_refcnt refcnt;
+     struct list_head dev_link;
+     struct list_head path_link;
+     struct module *owner;
+     bool enable;
+};
+
+#define to_coresight_device(d) container_of(d, struct coresight_device, dev)
+
+#define CORESIGHT_DEBUGFS_ENTRY(__name, __entry_name,                        \
+                              __mode, __get, __set, __fmt)           \
+DEFINE_SIMPLE_ATTRIBUTE(__name ## _ops, __get, __set, __fmt)         \
+static const struct coresight_ops_entry __name ## _entry = {         \
+     .name = __entry_name,                                           \
+     .mode = __mode,                                                 \
+     .ops  = &__name ## _ops                                         \
+}
+
+struct coresight_ops_sink {
+     int (*enable)(struct coresight_device *csdev);
+     void (*disable)(struct coresight_device *csdev);
+     void (*abort)(struct coresight_device *csdev);
+};
+
+struct coresight_ops_link {
+     int (*enable)(struct coresight_device *csdev, int iport, int oport);
+     void (*disable)(struct coresight_device *csdev, int iport, int oport);
+};
+
+struct coresight_ops_source {
+     int (*enable)(struct coresight_device *csdev);
+     void (*disable)(struct coresight_device *csdev);
+};
+
+struct coresight_ops {
+     const struct coresight_ops_sink *sink_ops;
+     const struct coresight_ops_link *link_ops;
+     const struct coresight_ops_source *source_ops;
+};
+
+#ifdef CONFIG_CORESIGHT
+extern struct coresight_device *
+coresight_register(struct coresight_desc *desc);
+extern void coresight_unregister(struct coresight_device *csdev);
+extern int coresight_enable(struct coresight_device *csdev);
+extern void coresight_disable(struct coresight_device *csdev);
+extern void coresight_abort(void);
+extern struct clk *coresight_get_clk(void);
+#else
+static inline struct coresight_device *
+coresight_register(struct coresight_desc *desc) { return NULL; }
+static inline void coresight_unregister(struct coresight_device *csdev) {}
+static inline int
+coresight_enable(struct coresight_device *csdev) { return -ENOSYS; }
+static inline void coresight_disable(struct coresight_device *csdev) {}
+static inline void coresight_abort(void) {}
+extern struct clk *coresight_get_clk(void) {};
   ^^^^^^                                     ^^

Not static and no return value.
That is cruft from a past era and should have been removed.
quoted
+#endif
+
+#endif
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help