}
 EXPORT_SYMBOL_GPL(coresight_get_percpu_sink);
 
-static int coresight_find_link_inport(struct coresight_device *csdev,
-                                     struct coresight_device *parent)
+static struct coresight_connection *
+coresight_find_out_connection(struct coresight_device *src_dev,
+                             struct coresight_device *dest_dev)
 {
        int i;
        struct coresight_connection *conn;
 
-       for (i = 0; i < parent->pdata->nr_outconns; i++) {
-               conn = parent->pdata->out_conns[i];
-               if (conn->dest_dev == csdev)
-                       return conn->dest_port;
+       for (i = 0; i < src_dev->pdata->nr_outconns; i++) {
+               conn = src_dev->pdata->out_conns[i];
+               if (conn->dest_dev == dest_dev)
+                       return conn;
        }
 
-       dev_err(&csdev->dev, "couldn't find inport, parent: %s, child: %s\n",
-               dev_name(&parent->dev), dev_name(&csdev->dev));
+       dev_err(&src_dev->dev,
+               "couldn't find output connection, src_dev: %s, dest_dev: %s\n",
+               dev_name(&src_dev->dev), dev_name(&dest_dev->dev));
 
-       return -ENODEV;
-}
-
-static int coresight_find_link_outport(struct coresight_device *csdev,
-                                      struct coresight_device *child)
-{
-       int i;
-       struct coresight_connection *conn;
-
-       for (i = 0; i < csdev->pdata->nr_outconns; i++) {
-               conn = csdev->pdata->out_conns[i];
-               if (conn->dest_dev == child)
-                       return conn->src_port;
-       }
-
-       dev_err(&csdev->dev, "couldn't find outport, parent: %s, child: %s\n",
-               dev_name(&csdev->dev), dev_name(&child->dev));
-
-       return -ENODEV;
+       return ERR_PTR(-ENODEV);
 }
 
 static inline u32 coresight_read_claim_tags(struct coresight_device *csdev)
 {
        int ret = 0;
        int link_subtype;
-       int inport, outport;
+       struct coresight_connection *inconn, *outconn;
 
        if (!parent || !child)
                return -EINVAL;
 
-       inport = coresight_find_link_inport(csdev, parent);
-       outport = coresight_find_link_outport(csdev, child);
+       inconn = coresight_find_out_connection(parent, csdev);
+       outconn = coresight_find_out_connection(csdev, child);
        link_subtype = csdev->subtype.link_subtype;
 
-       if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG && inport < 0)
-               return inport;
-       if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT && outport < 0)
-               return outport;
+       if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG && IS_ERR(inconn))
+               return PTR_ERR(inconn);
+       if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT && IS_ERR(outconn))
+               return PTR_ERR(outconn);
 
        if (link_ops(csdev)->enable) {
                ret = coresight_control_assoc_ectdev(csdev, true);
                if (!ret) {
-                       ret = link_ops(csdev)->enable(csdev, inport, outport);
+                       ret = link_ops(csdev)->enable(csdev, inconn, outconn);
                        if (ret)
                                coresight_control_assoc_ectdev(csdev, false);
                }
                                   struct coresight_device *parent,
                                   struct coresight_device *child)
 {
-       int i, nr_conns;
+       int i;
        int link_subtype;
-       int inport, outport;
+       struct coresight_connection *inconn, *outconn;
 
        if (!parent || !child)
                return;
 
-       inport = coresight_find_link_inport(csdev, parent);
-       outport = coresight_find_link_outport(csdev, child);
+       inconn = coresight_find_out_connection(parent, csdev);
+       outconn = coresight_find_out_connection(csdev, child);
        link_subtype = csdev->subtype.link_subtype;
 
-       if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG) {
-               nr_conns = csdev->pdata->high_inport;
-       } else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT) {
-               nr_conns = csdev->pdata->high_outport;
-       } else {
-               nr_conns = 1;
-       }
-
        if (link_ops(csdev)->disable) {
-               link_ops(csdev)->disable(csdev, inport, outport);
+               link_ops(csdev)->disable(csdev, inconn, outconn);
                coresight_control_assoc_ectdev(csdev, false);
        }
 
-       for (i = 0; i < nr_conns; i++)
-               if (atomic_read(&csdev->refcnt[i]) != 0)
+       if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG) {
+               for (i = 0; i < csdev->pdata->nr_inconns; i++)
+                       if (atomic_read(&csdev->pdata->in_conns[i]->dest_refcnt) !=
+                           0)
+                               return;
+       } else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT) {
+               for (i = 0; i < csdev->pdata->nr_outconns; i++)
+                       if (atomic_read(&csdev->pdata->out_conns[i]->src_refcnt) !=
+                           0)
+                               return;
+       } else {
+               if (atomic_read(&csdev->refcnt) != 0)
                        return;
+       }
 
        csdev->enable = false;
 }
                csdev->enable = true;
        }
 
-       atomic_inc(csdev->refcnt);
+       atomic_inc(&csdev->refcnt);
 
        return 0;
 }
  */
 static bool coresight_disable_source(struct coresight_device *csdev)
 {
-       if (atomic_dec_return(csdev->refcnt) == 0) {
+       if (atomic_dec_return(&csdev->refcnt) == 0) {
                if (source_ops(csdev)->disable)
                        source_ops(csdev)->disable(csdev, NULL);
                coresight_control_assoc_ectdev(csdev, false);
                 * source is already enabled.
                 */
                if (subtype == CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE)
-                       atomic_inc(csdev->refcnt);
+                       atomic_inc(&csdev->refcnt);
                goto out;
        }
 
        struct coresight_device *csdev = to_coresight_device(dev);
 
        fwnode_handle_put(csdev->dev.fwnode);
-       kfree(csdev->refcnt);
        kfree(csdev);
 }
 
 struct coresight_device *coresight_register(struct coresight_desc *desc)
 {
        int ret;
-       int link_subtype;
-       int nr_refcnts = 1;
-       atomic_t *refcnts = NULL;
        struct coresight_device *csdev;
        bool registered = false;
 
                goto err_out;
        }
 
-       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->high_inport;
-               else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT)
-                       nr_refcnts = desc->pdata->high_outport;
-       }
-
-       refcnts = kcalloc(nr_refcnts, sizeof(*refcnts), GFP_KERNEL);
-       if (!refcnts) {
-               ret = -ENOMEM;
-               kfree(csdev);
-               goto err_out;
-       }
-
-       csdev->refcnt = refcnts;
-
        csdev->pdata = desc->pdata;
 
        csdev->type = desc->type;
 
                drvdata->mode = CS_MODE_SYSFS;
        }
 
-       atomic_inc(csdev->refcnt);
+       atomic_inc(&csdev->refcnt);
 out:
        spin_unlock_irqrestore(&drvdata->spinlock, flags);
        return ret;
         * use for this session.
         */
        if (drvdata->pid == pid) {
-               atomic_inc(csdev->refcnt);
+               atomic_inc(&csdev->refcnt);
                goto out;
        }
 
                /* Associate with monitored process. */
                drvdata->pid = pid;
                drvdata->mode = CS_MODE_PERF;
-               atomic_inc(csdev->refcnt);
+               atomic_inc(&csdev->refcnt);
        }
 
 out:
 
        spin_lock_irqsave(&drvdata->spinlock, flags);
 
-       if (atomic_dec_return(csdev->refcnt)) {
+       if (atomic_dec_return(&csdev->refcnt)) {
                spin_unlock_irqrestore(&drvdata->spinlock, flags);
                return -EBUSY;
        }
        spin_lock_irqsave(&drvdata->spinlock, flags);
 
        /* Don't do anything if another tracer is using this sink */
-       if (atomic_read(csdev->refcnt) != 1)
+       if (atomic_read(&csdev->refcnt) != 1)
                goto out;
 
        __etb_disable_hw(drvdata);
 
        return rc;
 }
 
-static int funnel_enable(struct coresight_device *csdev, int inport,
-                        int outport)
+static int funnel_enable(struct coresight_device *csdev,
+                        struct coresight_connection *in,
+                        struct coresight_connection *out)
 {
        int rc = 0;
        struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
        bool first_enable = false;
 
        spin_lock_irqsave(&drvdata->spinlock, flags);
-       if (atomic_read(&csdev->refcnt[inport]) == 0) {
+       if (atomic_read(&in->dest_refcnt) == 0) {
                if (drvdata->base)
-                       rc = dynamic_funnel_enable_hw(drvdata, inport);
+                       rc = dynamic_funnel_enable_hw(drvdata, in->dest_port);
                if (!rc)
                        first_enable = true;
        }
        if (!rc)
-               atomic_inc(&csdev->refcnt[inport]);
+               atomic_inc(&in->dest_refcnt);
        spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
        if (first_enable)
-               dev_dbg(&csdev->dev, "FUNNEL inport %d enabled\n", inport);
+               dev_dbg(&csdev->dev, "FUNNEL inport %d enabled\n",
+                       in->dest_port);
        return rc;
 }
 
        CS_LOCK(drvdata->base);
 }
 
-static void funnel_disable(struct coresight_device *csdev, int inport,
-                          int outport)
+static void funnel_disable(struct coresight_device *csdev,
+                          struct coresight_connection *in,
+                          struct coresight_connection *out)
 {
        struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
        unsigned long flags;
        bool last_disable = false;
 
        spin_lock_irqsave(&drvdata->spinlock, flags);
-       if (atomic_dec_return(&csdev->refcnt[inport]) == 0) {
+       if (atomic_dec_return(&in->dest_refcnt) == 0) {
                if (drvdata->base)
-                       dynamic_funnel_disable_hw(drvdata, inport);
+                       dynamic_funnel_disable_hw(drvdata, in->dest_port);
                last_disable = true;
        }
        spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
        if (last_disable)
-               dev_dbg(&csdev->dev, "FUNNEL inport %d disabled\n", inport);
+               dev_dbg(&csdev->dev, "FUNNEL inport %d disabled\n",
+                       in->dest_port);
 }
 
 static const struct coresight_ops_link funnel_link_ops = {
 
        return of_property_read_bool(ep, "slave-mode");
 }
 
-static void of_coresight_get_ports_legacy(const struct device_node *node,
-                                         int *nr_inconns, int *nr_outconns)
-{
-       struct device_node *ep = NULL;
-       struct of_endpoint endpoint;
-       int in = 0, out = 0;
-
-       /*
-        * Avoid warnings in of_graph_get_next_endpoint()
-        * if the device doesn't have any graph connections
-        */
-       if (!of_graph_is_present(node))
-               return;
-       do {
-               ep = of_graph_get_next_endpoint(node, ep);
-               if (!ep)
-                       break;
-
-               if (of_graph_parse_endpoint(ep, &endpoint))
-                       continue;
-
-               if (of_coresight_legacy_ep_is_input(ep)) {
-                       in = (endpoint.port + 1 > in) ?
-                               endpoint.port + 1 : in;
-               } else {
-                       out = (endpoint.port + 1) > out ?
-                               endpoint.port + 1 : out;
-               }
-
-       } while (ep);
-
-       *nr_inconns = in;
-       *nr_outconns = out;
-}
-
 static struct device_node *of_coresight_get_port_parent(struct device_node *ep)
 {
        struct device_node *parent = of_graph_get_port_parent(ep);
        return parent;
 }
 
-static inline struct device_node *
-of_coresight_get_input_ports_node(const struct device_node *node)
-{
-       return of_get_child_by_name(node, "in-ports");
-}
-
 static inline struct device_node *
 of_coresight_get_output_ports_node(const struct device_node *node)
 {
        return of_get_child_by_name(node, "out-ports");
 }
 
-static inline int
-of_coresight_count_ports(struct device_node *port_parent)
-{
-       int i = 0;
-       struct device_node *ep = NULL;
-       struct of_endpoint endpoint;
-
-       while ((ep = of_graph_get_next_endpoint(port_parent, ep))) {
-               /* Defer error handling to parsing */
-               if (of_graph_parse_endpoint(ep, &endpoint))
-                       continue;
-               if (endpoint.port + 1 > i)
-                       i = endpoint.port + 1;
-       }
-
-       return i;
-}
-
-static void of_coresight_get_ports(const struct device_node *node,
-                                  int *nr_inconns, int *nr_outconns)
-{
-       struct device_node *input_ports = NULL, *output_ports = NULL;
-
-       input_ports = of_coresight_get_input_ports_node(node);
-       output_ports = of_coresight_get_output_ports_node(node);
-
-       if (input_ports || output_ports) {
-               if (input_ports) {
-                       *nr_inconns = of_coresight_count_ports(input_ports);
-                       of_node_put(input_ports);
-               }
-               if (output_ports) {
-                       *nr_outconns = of_coresight_count_ports(output_ports);
-                       of_node_put(output_ports);
-               }
-       } else {
-               /* Fall back to legacy DT bindings parsing */
-               of_coresight_get_ports_legacy(node, nr_inconns, nr_outconns);
-       }
-}
-
 static int of_coresight_get_cpu(struct device *dev)
 {
        int cpu;
        bool legacy_binding = false;
        struct device_node *node = dev->of_node;
 
-       /* Get the number of input and output port for this component */
-       of_coresight_get_ports(node, &pdata->high_inport, &pdata->high_outport);
-
-       /* If there are no output connections, we are done */
-       if (!pdata->high_outport)
-               return 0;
-
        parent = of_coresight_get_output_ports_node(node);
        /*
         * If the DT uses obsoleted bindings, the ports are listed
         * ports.
         */
        if (!parent) {
+               /*
+                * Avoid warnings in of_graph_get_next_endpoint()
+                * if the device doesn't have any graph connections
+                */
+               if (!of_graph_is_present(node))
+                       return 0;
                legacy_binding = true;
                parent = node;
                dev_warn_once(dev, "Uses obsolete Coresight DT bindings\n");
        struct coresight_connection conn, zero_conn = {};
        struct coresight_connection *new_conn;
 
-       pdata->nr_inconns = pdata->nr_outconns = 0;
        graph = acpi_get_coresight_graph(adev);
        if (!graph)
                return -ENOENT;
                        return dir;
 
                if (dir == ACPI_CORESIGHT_LINK_MASTER) {
-                       if (conn.src_port >= pdata->high_outport)
-                               pdata->high_outport = conn.src_port + 1;
                        new_conn = coresight_add_out_conn(dev, pdata, &conn);
                        if (IS_ERR(new_conn))
                                return PTR_ERR(new_conn);
-               } else {
-                       WARN_ON(pdata->high_inport == conn.dest_port + 1);
-                       /*
-                        * We do not track input port connections for a device.
-                        * However we need the highest port number described,
-                        * which can be recorded now and reuse this connection
-                        * record for an output connection. Hence, do not move
-                        * the ptr for input connections
-                        */
-                       if (conn.dest_port >= pdata->high_inport)
-                               pdata->high_inport = conn.dest_port + 1;
                }
        }
 
 
        return rc;
 }
 
-static int replicator_enable(struct coresight_device *csdev, int inport,
-                            int outport)
+static int replicator_enable(struct coresight_device *csdev,
+                            struct coresight_connection *in,
+                            struct coresight_connection *out)
 {
        int rc = 0;
        struct replicator_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
        bool first_enable = false;
 
        spin_lock_irqsave(&drvdata->spinlock, flags);
-       if (atomic_read(&csdev->refcnt[outport]) == 0) {
+       if (atomic_read(&out->src_refcnt) == 0) {
                if (drvdata->base)
-                       rc = dynamic_replicator_enable(drvdata, inport,
-                                                      outport);
+                       rc = dynamic_replicator_enable(drvdata, in->dest_port,
+                                                      out->src_port);
                if (!rc)
                        first_enable = true;
        }
        if (!rc)
-               atomic_inc(&csdev->refcnt[outport]);
+               atomic_inc(&out->src_refcnt);
        spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
        if (first_enable)
        CS_LOCK(drvdata->base);
 }
 
-static void replicator_disable(struct coresight_device *csdev, int inport,
-                              int outport)
+static void replicator_disable(struct coresight_device *csdev,
+                              struct coresight_connection *in,
+                              struct coresight_connection *out)
 {
        struct replicator_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
        unsigned long flags;
        bool last_disable = false;
 
        spin_lock_irqsave(&drvdata->spinlock, flags);
-       if (atomic_dec_return(&csdev->refcnt[outport]) == 0) {
+       if (atomic_dec_return(&out->src_refcnt) == 0) {
                if (drvdata->base)
-                       dynamic_replicator_disable(drvdata, inport, outport);
+                       dynamic_replicator_disable(drvdata, in->dest_port,
+                                                  out->src_port);
                last_disable = true;
        }
        spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
         * touched.
         */
        if (drvdata->mode == CS_MODE_SYSFS) {
-               atomic_inc(csdev->refcnt);
+               atomic_inc(&csdev->refcnt);
                goto out;
        }
 
        ret = tmc_etb_enable_hw(drvdata);
        if (!ret) {
                drvdata->mode = CS_MODE_SYSFS;
-               atomic_inc(csdev->refcnt);
+               atomic_inc(&csdev->refcnt);
        } else {
                /* Free up the buffer if we failed to enable */
                used = false;
                 * use for this session.
                 */
                if (drvdata->pid == pid) {
-                       atomic_inc(csdev->refcnt);
+                       atomic_inc(&csdev->refcnt);
                        break;
                }
 
                        /* Associate with monitored process. */
                        drvdata->pid = pid;
                        drvdata->mode = CS_MODE_PERF;
-                       atomic_inc(csdev->refcnt);
+                       atomic_inc(&csdev->refcnt);
                }
        } while (0);
        spin_unlock_irqrestore(&drvdata->spinlock, flags);
                return -EBUSY;
        }
 
-       if (atomic_dec_return(csdev->refcnt)) {
+       if (atomic_dec_return(&csdev->refcnt)) {
                spin_unlock_irqrestore(&drvdata->spinlock, flags);
                return -EBUSY;
        }
 }
 
 static int tmc_enable_etf_link(struct coresight_device *csdev,
-                              int inport, int outport)
+                              struct coresight_connection *in,
+                              struct coresight_connection *out)
 {
        int ret = 0;
        unsigned long flags;
                return -EBUSY;
        }
 
-       if (atomic_read(&csdev->refcnt[0]) == 0) {
+       if (atomic_read(&csdev->refcnt) == 0) {
                ret = tmc_etf_enable_hw(drvdata);
                if (!ret) {
                        drvdata->mode = CS_MODE_SYSFS;
                }
        }
        if (!ret)
-               atomic_inc(&csdev->refcnt[0]);
+               atomic_inc(&csdev->refcnt);
        spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
        if (first_enable)
 }
 
 static void tmc_disable_etf_link(struct coresight_device *csdev,
-                                int inport, int outport)
+                                struct coresight_connection *in,
+                                struct coresight_connection *out)
 {
        unsigned long flags;
        struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
                return;
        }
 
-       if (atomic_dec_return(&csdev->refcnt[0]) == 0) {
+       if (atomic_dec_return(&csdev->refcnt) == 0) {
                tmc_etf_disable_hw(drvdata);
                drvdata->mode = CS_MODE_DISABLED;
                last_disable = true;
        spin_lock_irqsave(&drvdata->spinlock, flags);
 
        /* Don't do anything if another tracer is using this sink */
-       if (atomic_read(csdev->refcnt) != 1)
+       if (atomic_read(&csdev->refcnt) != 1)
                goto out;
 
        CS_UNLOCK(drvdata->base);
 
         * touched, even if the buffer size has changed.
         */
        if (drvdata->mode == CS_MODE_SYSFS) {
-               atomic_inc(csdev->refcnt);
+               atomic_inc(&csdev->refcnt);
                goto out;
        }
 
        ret = tmc_etr_enable_hw(drvdata, drvdata->sysfs_buf);
        if (!ret) {
                drvdata->mode = CS_MODE_SYSFS;
-               atomic_inc(csdev->refcnt);
+               atomic_inc(&csdev->refcnt);
        }
 out:
        spin_unlock_irqrestore(&drvdata->spinlock, flags);
        spin_lock_irqsave(&drvdata->spinlock, flags);
 
        /* Don't do anything if another tracer is using this sink */
-       if (atomic_read(csdev->refcnt) != 1) {
+       if (atomic_read(&csdev->refcnt) != 1) {
                spin_unlock_irqrestore(&drvdata->spinlock, flags);
                goto out;
        }
         * use for this session.
         */
        if (drvdata->pid == pid) {
-               atomic_inc(csdev->refcnt);
+               atomic_inc(&csdev->refcnt);
                goto unlock_out;
        }
 
                drvdata->pid = pid;
                drvdata->mode = CS_MODE_PERF;
                drvdata->perf_buf = etr_perf->etr_buf;
-               atomic_inc(csdev->refcnt);
+               atomic_inc(&csdev->refcnt);
        }
 
 unlock_out:
                return -EBUSY;
        }
 
-       if (atomic_dec_return(csdev->refcnt)) {
+       if (atomic_dec_return(&csdev->refcnt)) {
                spin_unlock_irqrestore(&drvdata->spinlock, flags);
                return -EBUSY;
        }
 
        CS_LOCK(drvdata->base);
 }
 
-static int tpda_enable(struct coresight_device *csdev, int inport, int outport)
+static int tpda_enable(struct coresight_device *csdev,
+                      struct coresight_connection *in,
+                      struct coresight_connection *out)
 {
        struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
        spin_lock(&drvdata->spinlock);
-       if (atomic_read(&csdev->refcnt[inport]) == 0)
-               __tpda_enable(drvdata, inport);
+       if (atomic_read(&in->dest_refcnt) == 0)
+               __tpda_enable(drvdata, in->dest_port);
 
-       atomic_inc(&csdev->refcnt[inport]);
+       atomic_inc(&in->dest_refcnt);
        spin_unlock(&drvdata->spinlock);
 
-       dev_dbg(drvdata->dev, "TPDA inport %d enabled.\n", inport);
+       dev_dbg(drvdata->dev, "TPDA inport %d enabled.\n", in->dest_port);
        return 0;
 }
 
        CS_LOCK(drvdata->base);
 }
 
-static void tpda_disable(struct coresight_device *csdev, int inport,
-                          int outport)
+static void tpda_disable(struct coresight_device *csdev,
+                        struct coresight_connection *in,
+                        struct coresight_connection *out)
 {
        struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
 
        spin_lock(&drvdata->spinlock);
-       if (atomic_dec_return(&csdev->refcnt[inport]) == 0)
-               __tpda_disable(drvdata, inport);
+       if (atomic_dec_return(&in->dest_refcnt) == 0)
+               __tpda_disable(drvdata, in->dest_port);
 
        spin_unlock(&drvdata->spinlock);
 
-       dev_dbg(drvdata->dev, "TPDA inport %d disabled\n", inport);
+       dev_dbg(drvdata->dev, "TPDA inport %d disabled\n", in->dest_port);
 }
 
 static const struct coresight_ops_link tpda_link_ops = {
 
                       void *__unused)
 {
        tpiu_enable_hw(&csdev->access);
-       atomic_inc(csdev->refcnt);
+       atomic_inc(&csdev->refcnt);
        dev_dbg(&csdev->dev, "TPIU enabled\n");
        return 0;
 }
 
 static int tpiu_disable(struct coresight_device *csdev)
 {
-       if (atomic_dec_return(csdev->refcnt))
+       if (atomic_dec_return(&csdev->refcnt))
                return -EBUSY;
 
        tpiu_disable_hw(&csdev->access);
 
                goto out;
        }
 
-       if (atomic_read(drvdata->csdev->refcnt)) {
+       if (atomic_read(&drvdata->csdev->refcnt)) {
                ret = -EBUSY;
                goto out;
        }
        if (ret)
                goto out;
 
-       atomic_inc(csdev->refcnt);
+       atomic_inc(&csdev->refcnt);
 
        dev_dbg(&csdev->dev, "Ultrasoc SMB enabled\n");
 out:
                goto out;
        }
 
-       if (atomic_dec_return(csdev->refcnt)) {
+       if (atomic_dec_return(&csdev->refcnt)) {
                ret = -EBUSY;
                goto out;
        }
        mutex_lock(&drvdata->mutex);
 
        /* Don't do anything if another tracer is using this sink. */
-       if (atomic_read(csdev->refcnt) != 1)
+       if (atomic_read(&csdev->refcnt) != 1)
                goto out;
 
        smb_disable_hw(drvdata);
 
  *            unloaded the connection leaves an empty slot.
  */
 struct coresight_platform_data {
-       int high_inport;
-       int high_outport;
        int nr_inconns;
        int nr_outconns;
        struct coresight_connection **out_conns;
        struct coresight_device *dest_dev;
        struct coresight_sysfs_link *link;
        struct coresight_device *src_dev;
+       atomic_t src_refcnt;
+       atomic_t dest_refcnt;
 };
 
 /**
        const struct coresight_ops *ops;
        struct csdev_access access;
        struct device dev;
-       atomic_t *refcnt;
+       atomic_t refcnt;
        bool orphan;
        bool enable;    /* true only if configured as part of a path */
        /* sink specific fields */
  * @disable:   disables flow between iport and oport.
  */
 struct coresight_ops_link {
-       int (*enable)(struct coresight_device *csdev, int iport, int oport);
-       void (*disable)(struct coresight_device *csdev, int iport, int oport);
+       int (*enable)(struct coresight_device *csdev,
+                     struct coresight_connection *in,
+                     struct coresight_connection *out);
+       void (*disable)(struct coresight_device *csdev,
+                       struct coresight_connection *in,
+                       struct coresight_connection *out);
 };
 
 /**