blob: 62faa58a76ea5fffccb79292fe44df72bfa037c0 [file] [log] [blame]
Pratik Patela06ae862014-11-03 11:07:35 -07001/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/kernel.h>
Pratik Patela06ae862014-11-03 11:07:35 -070014#include <linux/init.h>
15#include <linux/types.h>
16#include <linux/device.h>
17#include <linux/io.h>
18#include <linux/err.h>
19#include <linux/export.h>
20#include <linux/slab.h>
21#include <linux/mutex.h>
22#include <linux/clk.h>
23#include <linux/coresight.h>
24#include <linux/of_platform.h>
25#include <linux/delay.h>
Mathieu Poirier5da53252016-02-17 17:51:47 -070026#include <linux/pm_runtime.h>
Pratik Patela06ae862014-11-03 11:07:35 -070027
28#include "coresight-priv.h"
29
30static DEFINE_MUTEX(coresight_mutex);
31
Mathieu Poirierb3e94402016-02-17 17:51:45 -070032/**
33 * struct coresight_node - elements of a path, from source to sink
34 * @csdev: Address of an element.
35 * @link: hook to the list.
36 */
37struct coresight_node {
38 struct coresight_device *csdev;
39 struct list_head link;
40};
41
42/*
43 * When operating Coresight drivers from the sysFS interface, only a single
44 * path can exist from a tracer (associated to a CPU) to a sink.
45 */
Mathieu Poiriera685d682016-05-03 11:33:38 -060046static DEFINE_PER_CPU(struct list_head *, tracer_path);
47
48/*
49 * As of this writing only a single STM can be found in CS topologies. Since
50 * there is no way to know if we'll ever see more and what kind of
51 * configuration they will enact, for the time being only define a single path
52 * for STM.
53 */
54static struct list_head *stm_path;
Mathieu Poirierb3e94402016-02-17 17:51:45 -070055
Pratik Patela06ae862014-11-03 11:07:35 -070056static int coresight_id_match(struct device *dev, void *data)
57{
58 int trace_id, i_trace_id;
59 struct coresight_device *csdev, *i_csdev;
60
61 csdev = data;
62 i_csdev = to_coresight_device(dev);
63
64 /*
65 * No need to care about oneself and components that are not
66 * sources or not enabled
67 */
68 if (i_csdev == csdev || !i_csdev->enable ||
69 i_csdev->type != CORESIGHT_DEV_TYPE_SOURCE)
70 return 0;
71
72 /* Get the source ID for both compoment */
73 trace_id = source_ops(csdev)->trace_id(csdev);
74 i_trace_id = source_ops(i_csdev)->trace_id(i_csdev);
75
76 /* All you need is one */
77 if (trace_id == i_trace_id)
78 return 1;
79
80 return 0;
81}
82
83static int coresight_source_is_unique(struct coresight_device *csdev)
84{
85 int trace_id = source_ops(csdev)->trace_id(csdev);
86
87 /* this shouldn't happen */
88 if (trace_id < 0)
89 return 0;
90
91 return !bus_for_each_dev(&coresight_bustype, NULL,
92 csdev, coresight_id_match);
93}
94
Mathieu Poirierb3e94402016-02-17 17:51:45 -070095static int coresight_find_link_inport(struct coresight_device *csdev,
96 struct coresight_device *parent)
Pratik Patela06ae862014-11-03 11:07:35 -070097{
98 int i;
Pratik Patela06ae862014-11-03 11:07:35 -070099 struct coresight_connection *conn;
100
Pratik Patela06ae862014-11-03 11:07:35 -0700101 for (i = 0; i < parent->nr_outport; i++) {
102 conn = &parent->conns[i];
103 if (conn->child_dev == csdev)
104 return conn->child_port;
105 }
106
107 dev_err(&csdev->dev, "couldn't find inport, parent: %s, child: %s\n",
108 dev_name(&parent->dev), dev_name(&csdev->dev));
109
110 return 0;
111}
112
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700113static int coresight_find_link_outport(struct coresight_device *csdev,
114 struct coresight_device *child)
Pratik Patela06ae862014-11-03 11:07:35 -0700115{
116 int i;
Pratik Patela06ae862014-11-03 11:07:35 -0700117 struct coresight_connection *conn;
118
Pratik Patela06ae862014-11-03 11:07:35 -0700119 for (i = 0; i < csdev->nr_outport; i++) {
120 conn = &csdev->conns[i];
121 if (conn->child_dev == child)
122 return conn->outport;
123 }
124
125 dev_err(&csdev->dev, "couldn't find outport, parent: %s, child: %s\n",
126 dev_name(&csdev->dev), dev_name(&child->dev));
127
128 return 0;
129}
130
Mathieu Poiriere827d452016-02-17 17:51:59 -0700131static int coresight_enable_sink(struct coresight_device *csdev, u32 mode)
Pratik Patela06ae862014-11-03 11:07:35 -0700132{
133 int ret;
134
135 if (!csdev->enable) {
136 if (sink_ops(csdev)->enable) {
Mathieu Poiriere827d452016-02-17 17:51:59 -0700137 ret = sink_ops(csdev)->enable(csdev, mode);
Pratik Patela06ae862014-11-03 11:07:35 -0700138 if (ret)
139 return ret;
140 }
141 csdev->enable = true;
142 }
143
144 atomic_inc(csdev->refcnt);
145
146 return 0;
147}
148
149static void coresight_disable_sink(struct coresight_device *csdev)
150{
151 if (atomic_dec_return(csdev->refcnt) == 0) {
152 if (sink_ops(csdev)->disable) {
153 sink_ops(csdev)->disable(csdev);
154 csdev->enable = false;
155 }
156 }
157}
158
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700159static int coresight_enable_link(struct coresight_device *csdev,
160 struct coresight_device *parent,
161 struct coresight_device *child)
Pratik Patela06ae862014-11-03 11:07:35 -0700162{
163 int ret;
164 int link_subtype;
165 int refport, inport, outport;
166
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700167 if (!parent || !child)
168 return -EINVAL;
169
170 inport = coresight_find_link_inport(csdev, parent);
171 outport = coresight_find_link_outport(csdev, child);
Pratik Patela06ae862014-11-03 11:07:35 -0700172 link_subtype = csdev->subtype.link_subtype;
173
174 if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG)
175 refport = inport;
176 else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT)
177 refport = outport;
178 else
179 refport = 0;
180
181 if (atomic_inc_return(&csdev->refcnt[refport]) == 1) {
182 if (link_ops(csdev)->enable) {
183 ret = link_ops(csdev)->enable(csdev, inport, outport);
184 if (ret)
185 return ret;
186 }
187 }
188
189 csdev->enable = true;
190
191 return 0;
192}
193
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700194static void coresight_disable_link(struct coresight_device *csdev,
195 struct coresight_device *parent,
196 struct coresight_device *child)
Pratik Patela06ae862014-11-03 11:07:35 -0700197{
198 int i, nr_conns;
199 int link_subtype;
200 int refport, inport, outport;
201
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700202 if (!parent || !child)
203 return;
204
205 inport = coresight_find_link_inport(csdev, parent);
206 outport = coresight_find_link_outport(csdev, child);
Pratik Patela06ae862014-11-03 11:07:35 -0700207 link_subtype = csdev->subtype.link_subtype;
208
209 if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG) {
210 refport = inport;
211 nr_conns = csdev->nr_inport;
212 } else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT) {
213 refport = outport;
214 nr_conns = csdev->nr_outport;
215 } else {
216 refport = 0;
217 nr_conns = 1;
218 }
219
220 if (atomic_dec_return(&csdev->refcnt[refport]) == 0) {
221 if (link_ops(csdev)->disable)
222 link_ops(csdev)->disable(csdev, inport, outport);
223 }
224
225 for (i = 0; i < nr_conns; i++)
226 if (atomic_read(&csdev->refcnt[i]) != 0)
227 return;
228
229 csdev->enable = false;
230}
231
Mathieu Poirier22fd5322016-02-17 17:51:52 -0700232static int coresight_enable_source(struct coresight_device *csdev, u32 mode)
Pratik Patela06ae862014-11-03 11:07:35 -0700233{
234 int ret;
235
236 if (!coresight_source_is_unique(csdev)) {
237 dev_warn(&csdev->dev, "traceID %d not unique\n",
238 source_ops(csdev)->trace_id(csdev));
239 return -EINVAL;
240 }
241
242 if (!csdev->enable) {
243 if (source_ops(csdev)->enable) {
Mathieu Poirier882d5e12016-02-17 17:51:57 -0700244 ret = source_ops(csdev)->enable(csdev, NULL, mode);
Pratik Patela06ae862014-11-03 11:07:35 -0700245 if (ret)
246 return ret;
247 }
248 csdev->enable = true;
249 }
250
251 atomic_inc(csdev->refcnt);
252
253 return 0;
254}
255
256static void coresight_disable_source(struct coresight_device *csdev)
257{
258 if (atomic_dec_return(csdev->refcnt) == 0) {
259 if (source_ops(csdev)->disable) {
Mathieu Poirier68905d72016-08-25 15:19:10 -0600260 source_ops(csdev)->disable(csdev, NULL);
Pratik Patela06ae862014-11-03 11:07:35 -0700261 csdev->enable = false;
262 }
263 }
264}
265
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700266void coresight_disable_path(struct list_head *path)
Pratik Patela06ae862014-11-03 11:07:35 -0700267{
Mathieu Poirierdc2c4ef2016-05-03 11:34:00 -0600268 u32 type;
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700269 struct coresight_node *nd;
270 struct coresight_device *csdev, *parent, *child;
271
272 list_for_each_entry(nd, path, link) {
273 csdev = nd->csdev;
Mathieu Poirierdc2c4ef2016-05-03 11:34:00 -0600274 type = csdev->type;
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700275
Mathieu Poirierdc2c4ef2016-05-03 11:34:00 -0600276 /*
277 * ETF devices are tricky... They can be a link or a sink,
278 * depending on how they are configured. If an ETF has been
279 * "activated" it will be configured as a sink, otherwise
280 * go ahead with the link configuration.
281 */
282 if (type == CORESIGHT_DEV_TYPE_LINKSINK)
283 type = (csdev == coresight_get_sink(path)) ?
284 CORESIGHT_DEV_TYPE_SINK :
285 CORESIGHT_DEV_TYPE_LINK;
286
287 switch (type) {
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700288 case CORESIGHT_DEV_TYPE_SINK:
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700289 coresight_disable_sink(csdev);
290 break;
291 case CORESIGHT_DEV_TYPE_SOURCE:
292 /* sources are disabled from either sysFS or Perf */
293 break;
294 case CORESIGHT_DEV_TYPE_LINK:
295 parent = list_prev_entry(nd, link)->csdev;
296 child = list_next_entry(nd, link)->csdev;
297 coresight_disable_link(csdev, parent, child);
298 break;
299 default:
300 break;
301 }
302 }
303}
304
Mathieu Poiriere827d452016-02-17 17:51:59 -0700305int coresight_enable_path(struct list_head *path, u32 mode)
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700306{
307
Pratik Patela06ae862014-11-03 11:07:35 -0700308 int ret = 0;
Mathieu Poirierdc2c4ef2016-05-03 11:34:00 -0600309 u32 type;
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700310 struct coresight_node *nd;
311 struct coresight_device *csdev, *parent, *child;
Pratik Patela06ae862014-11-03 11:07:35 -0700312
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700313 list_for_each_entry_reverse(nd, path, link) {
314 csdev = nd->csdev;
Mathieu Poirierdc2c4ef2016-05-03 11:34:00 -0600315 type = csdev->type;
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700316
Mathieu Poirierdc2c4ef2016-05-03 11:34:00 -0600317 /*
318 * ETF devices are tricky... They can be a link or a sink,
319 * depending on how they are configured. If an ETF has been
320 * "activated" it will be configured as a sink, otherwise
321 * go ahead with the link configuration.
322 */
323 if (type == CORESIGHT_DEV_TYPE_LINKSINK)
324 type = (csdev == coresight_get_sink(path)) ?
325 CORESIGHT_DEV_TYPE_SINK :
326 CORESIGHT_DEV_TYPE_LINK;
327
328 switch (type) {
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700329 case CORESIGHT_DEV_TYPE_SINK:
Mathieu Poiriere827d452016-02-17 17:51:59 -0700330 ret = coresight_enable_sink(csdev, mode);
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700331 if (ret)
332 goto err;
333 break;
334 case CORESIGHT_DEV_TYPE_SOURCE:
335 /* sources are enabled from either sysFS or Perf */
336 break;
337 case CORESIGHT_DEV_TYPE_LINK:
338 parent = list_prev_entry(nd, link)->csdev;
339 child = list_next_entry(nd, link)->csdev;
340 ret = coresight_enable_link(csdev, parent, child);
341 if (ret)
342 goto err;
343 break;
344 default:
Pratik Patela06ae862014-11-03 11:07:35 -0700345 goto err;
Pratik Patela06ae862014-11-03 11:07:35 -0700346 }
347 }
348
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700349out:
Pratik Patela06ae862014-11-03 11:07:35 -0700350 return ret;
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700351err:
352 coresight_disable_path(path);
353 goto out;
Pratik Patela06ae862014-11-03 11:07:35 -0700354}
355
Mathieu Poirierb6404e22016-02-17 17:51:46 -0700356struct coresight_device *coresight_get_sink(struct list_head *path)
357{
358 struct coresight_device *csdev;
359
360 if (!path)
361 return NULL;
362
363 csdev = list_last_entry(path, struct coresight_node, link)->csdev;
364 if (csdev->type != CORESIGHT_DEV_TYPE_SINK &&
365 csdev->type != CORESIGHT_DEV_TYPE_LINKSINK)
366 return NULL;
367
368 return csdev;
369}
370
Mathieu Poirierebb45d72016-11-29 09:47:14 -0700371static int coresight_enabled_sink(struct device *dev, void *data)
372{
373 bool *reset = data;
374 struct coresight_device *csdev = to_coresight_device(dev);
375
376 if ((csdev->type == CORESIGHT_DEV_TYPE_SINK ||
377 csdev->type == CORESIGHT_DEV_TYPE_LINKSINK) &&
378 csdev->activated) {
379 /*
380 * Now that we have a handle on the sink for this session,
381 * disable the sysFS "enable_sink" flag so that possible
382 * concurrent perf session that wish to use another sink don't
383 * trip on it. Doing so has no ramification for the current
384 * session.
385 */
386 if (*reset)
387 csdev->activated = false;
388
389 return 1;
390 }
391
392 return 0;
393}
394
395/**
396 * coresight_get_enabled_sink - returns the first enabled sink found on the bus
397 * @deactivate: Whether the 'enable_sink' flag should be reset
398 *
399 * When operated from perf the deactivate parameter should be set to 'true'.
400 * That way the "enabled_sink" flag of the sink that was selected can be reset,
401 * allowing for other concurrent perf sessions to choose a different sink.
402 *
403 * When operated from sysFS users have full control and as such the deactivate
404 * parameter should be set to 'false', hence mandating users to explicitly
405 * clear the flag.
406 */
407struct coresight_device *coresight_get_enabled_sink(bool deactivate)
408{
409 struct device *dev = NULL;
410
411 dev = bus_find_device(&coresight_bustype, NULL, &deactivate,
412 coresight_enabled_sink);
413
414 return dev ? to_coresight_device(dev) : NULL;
415}
416
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700417/**
418 * _coresight_build_path - recursively build a path from a @csdev to a sink.
419 * @csdev: The device to start from.
420 * @path: The list to add devices to.
421 *
422 * The tree of Coresight device is traversed until an activated sink is
423 * found. From there the sink is added to the list along with all the
424 * devices that led to that point - the end result is a list from source
425 * to sink. In that list the source is the first device and the sink the
426 * last one.
427 */
428static int _coresight_build_path(struct coresight_device *csdev,
Mathieu Poirierebb45d72016-11-29 09:47:14 -0700429 struct coresight_device *sink,
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700430 struct list_head *path)
Pratik Patela06ae862014-11-03 11:07:35 -0700431{
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700432 int i;
433 bool found = false;
434 struct coresight_node *node;
Pratik Patela06ae862014-11-03 11:07:35 -0700435
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700436 /* An activated sink has been found. Enqueue the element */
Mathieu Poirierebb45d72016-11-29 09:47:14 -0700437 if (csdev == sink)
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700438 goto out;
439
440 /* Not a sink - recursively explore each port found on this element */
441 for (i = 0; i < csdev->nr_outport; i++) {
Suzuki K Pouloseec48a1d2016-06-14 11:17:12 -0600442 struct coresight_device *child_dev = csdev->conns[i].child_dev;
443
Mathieu Poirierebb45d72016-11-29 09:47:14 -0700444 if (child_dev &&
445 _coresight_build_path(child_dev, sink, path) == 0) {
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700446 found = true;
447 break;
Pratik Patela06ae862014-11-03 11:07:35 -0700448 }
449 }
450
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700451 if (!found)
452 return -ENODEV;
Pratik Patela06ae862014-11-03 11:07:35 -0700453
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700454out:
455 /*
456 * A path from this element to a sink has been found. The elements
457 * leading to the sink are already enqueued, all that is left to do
Mathieu Poirier5da53252016-02-17 17:51:47 -0700458 * is tell the PM runtime core we need this element and add a node
459 * for it.
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700460 */
461 node = kzalloc(sizeof(struct coresight_node), GFP_KERNEL);
462 if (!node)
463 return -ENOMEM;
Pratik Patela06ae862014-11-03 11:07:35 -0700464
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700465 node->csdev = csdev;
466 list_add(&node->link, path);
Mathieu Poirier5da53252016-02-17 17:51:47 -0700467 pm_runtime_get_sync(csdev->dev.parent);
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700468
469 return 0;
470}
471
Mathieu Poirierebb45d72016-11-29 09:47:14 -0700472struct list_head *coresight_build_path(struct coresight_device *source,
473 struct coresight_device *sink)
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700474{
475 struct list_head *path;
Suzuki K Poulose5014e902016-05-06 15:35:50 +0100476 int rc;
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700477
Mathieu Poirierebb45d72016-11-29 09:47:14 -0700478 if (!sink)
479 return ERR_PTR(-EINVAL);
480
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700481 path = kzalloc(sizeof(struct list_head), GFP_KERNEL);
482 if (!path)
Mathieu Poirier8e67cdb2016-09-08 16:50:38 -0600483 return ERR_PTR(-ENOMEM);
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700484
485 INIT_LIST_HEAD(path);
486
Mathieu Poirierebb45d72016-11-29 09:47:14 -0700487 rc = _coresight_build_path(source, sink, path);
Suzuki K Poulose5014e902016-05-06 15:35:50 +0100488 if (rc) {
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700489 kfree(path);
Suzuki K Poulose5014e902016-05-06 15:35:50 +0100490 return ERR_PTR(rc);
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700491 }
492
493 return path;
494}
495
496/**
497 * coresight_release_path - release a previously built path.
498 * @path: the path to release.
499 *
500 * Go through all the elements of a path and 1) removed it from the list and
501 * 2) free the memory allocated for each node.
502 */
503void coresight_release_path(struct list_head *path)
504{
Mathieu Poirier5da53252016-02-17 17:51:47 -0700505 struct coresight_device *csdev;
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700506 struct coresight_node *nd, *next;
507
508 list_for_each_entry_safe(nd, next, path, link) {
Mathieu Poirier5da53252016-02-17 17:51:47 -0700509 csdev = nd->csdev;
510
511 pm_runtime_put_sync(csdev->dev.parent);
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700512 list_del(&nd->link);
513 kfree(nd);
514 }
515
516 kfree(path);
517 path = NULL;
Pratik Patela06ae862014-11-03 11:07:35 -0700518}
519
Mathieu Poiriera685d682016-05-03 11:33:38 -0600520/** coresight_validate_source - make sure a source has the right credentials
521 * @csdev: the device structure for a source.
522 * @function: the function this was called from.
523 *
524 * Assumes the coresight_mutex is held.
525 */
526static int coresight_validate_source(struct coresight_device *csdev,
527 const char *function)
528{
529 u32 type, subtype;
530
531 type = csdev->type;
532 subtype = csdev->subtype.source_subtype;
533
534 if (type != CORESIGHT_DEV_TYPE_SOURCE) {
535 dev_err(&csdev->dev, "wrong device type in %s\n", function);
536 return -EINVAL;
537 }
538
539 if (subtype != CORESIGHT_DEV_SUBTYPE_SOURCE_PROC &&
540 subtype != CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE) {
541 dev_err(&csdev->dev, "wrong device subtype in %s\n", function);
542 return -EINVAL;
543 }
544
545 return 0;
546}
547
Pratik Patela06ae862014-11-03 11:07:35 -0700548int coresight_enable(struct coresight_device *csdev)
549{
Mathieu Poiriera685d682016-05-03 11:33:38 -0600550 int cpu, ret = 0;
Mathieu Poirierebb45d72016-11-29 09:47:14 -0700551 struct coresight_device *sink;
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700552 struct list_head *path;
Suzuki K Poulose41830b82017-06-05 14:15:03 -0600553 enum coresight_dev_subtype_source subtype;
554
555 subtype = csdev->subtype.source_subtype;
Pratik Patela06ae862014-11-03 11:07:35 -0700556
557 mutex_lock(&coresight_mutex);
Mathieu Poiriera685d682016-05-03 11:33:38 -0600558
559 ret = coresight_validate_source(csdev, __func__);
560 if (ret)
Pratik Patela06ae862014-11-03 11:07:35 -0700561 goto out;
Mathieu Poiriera685d682016-05-03 11:33:38 -0600562
Suzuki K Poulose41830b82017-06-05 14:15:03 -0600563 if (csdev->enable) {
564 /*
565 * There could be multiple applications driving the software
566 * source. So keep the refcount for each such user when the
567 * source is already enabled.
568 */
569 if (subtype == CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE)
570 atomic_inc(csdev->refcnt);
Pratik Patela06ae862014-11-03 11:07:35 -0700571 goto out;
Suzuki K Poulose41830b82017-06-05 14:15:03 -0600572 }
Pratik Patela06ae862014-11-03 11:07:35 -0700573
Mathieu Poirierebb45d72016-11-29 09:47:14 -0700574 /*
575 * Search for a valid sink for this session but don't reset the
576 * "enable_sink" flag in sysFS. Users get to do that explicitly.
577 */
578 sink = coresight_get_enabled_sink(false);
579 if (!sink) {
580 ret = -EINVAL;
581 goto out;
582 }
583
584 path = coresight_build_path(csdev, sink);
Suzuki K Poulose5014e902016-05-06 15:35:50 +0100585 if (IS_ERR(path)) {
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700586 pr_err("building path(s) failed\n");
Suzuki K Poulose5014e902016-05-06 15:35:50 +0100587 ret = PTR_ERR(path);
Pratik Patela06ae862014-11-03 11:07:35 -0700588 goto out;
589 }
590
Mathieu Poiriere827d452016-02-17 17:51:59 -0700591 ret = coresight_enable_path(path, CS_MODE_SYSFS);
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700592 if (ret)
593 goto err_path;
594
Mathieu Poirier22fd5322016-02-17 17:51:52 -0700595 ret = coresight_enable_source(csdev, CS_MODE_SYSFS);
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700596 if (ret)
597 goto err_source;
598
Suzuki K Poulose41830b82017-06-05 14:15:03 -0600599 switch (subtype) {
Mathieu Poiriera685d682016-05-03 11:33:38 -0600600 case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC:
601 /*
602 * When working from sysFS it is important to keep track
603 * of the paths that were created so that they can be
604 * undone in 'coresight_disable()'. Since there can only
605 * be a single session per tracer (when working from sysFS)
606 * a per-cpu variable will do just fine.
607 */
608 cpu = source_ops(csdev)->cpu_id(csdev);
609 per_cpu(tracer_path, cpu) = path;
610 break;
611 case CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE:
612 stm_path = path;
613 break;
614 default:
615 /* We can't be here */
616 break;
617 }
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700618
Pratik Patela06ae862014-11-03 11:07:35 -0700619out:
620 mutex_unlock(&coresight_mutex);
621 return ret;
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700622
623err_source:
624 coresight_disable_path(path);
625
626err_path:
627 coresight_release_path(path);
628 goto out;
Pratik Patela06ae862014-11-03 11:07:35 -0700629}
630EXPORT_SYMBOL_GPL(coresight_enable);
631
632void coresight_disable(struct coresight_device *csdev)
633{
Mathieu Poiriera685d682016-05-03 11:33:38 -0600634 int cpu, ret;
635 struct list_head *path = NULL;
Pratik Patela06ae862014-11-03 11:07:35 -0700636
637 mutex_lock(&coresight_mutex);
Mathieu Poiriera685d682016-05-03 11:33:38 -0600638
639 ret = coresight_validate_source(csdev, __func__);
640 if (ret)
Pratik Patela06ae862014-11-03 11:07:35 -0700641 goto out;
Mathieu Poiriera685d682016-05-03 11:33:38 -0600642
Pratik Patela06ae862014-11-03 11:07:35 -0700643 if (!csdev->enable)
644 goto out;
645
Mathieu Poiriera685d682016-05-03 11:33:38 -0600646 switch (csdev->subtype.source_subtype) {
647 case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC:
648 cpu = source_ops(csdev)->cpu_id(csdev);
649 path = per_cpu(tracer_path, cpu);
650 per_cpu(tracer_path, cpu) = NULL;
651 break;
652 case CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE:
653 path = stm_path;
654 stm_path = NULL;
655 break;
656 default:
657 /* We can't be here */
658 break;
659 }
660
Pratik Patela06ae862014-11-03 11:07:35 -0700661 coresight_disable_source(csdev);
Mathieu Poirierb3e94402016-02-17 17:51:45 -0700662 coresight_disable_path(path);
663 coresight_release_path(path);
Pratik Patela06ae862014-11-03 11:07:35 -0700664
665out:
666 mutex_unlock(&coresight_mutex);
667}
668EXPORT_SYMBOL_GPL(coresight_disable);
669
670static ssize_t enable_sink_show(struct device *dev,
671 struct device_attribute *attr, char *buf)
672{
673 struct coresight_device *csdev = to_coresight_device(dev);
674
Li Pengchenge8dc27d2016-05-03 11:33:35 -0600675 return scnprintf(buf, PAGE_SIZE, "%u\n", csdev->activated);
Pratik Patela06ae862014-11-03 11:07:35 -0700676}
677
678static ssize_t enable_sink_store(struct device *dev,
679 struct device_attribute *attr,
680 const char *buf, size_t size)
681{
682 int ret;
683 unsigned long val;
684 struct coresight_device *csdev = to_coresight_device(dev);
685
686 ret = kstrtoul(buf, 10, &val);
687 if (ret)
688 return ret;
689
690 if (val)
691 csdev->activated = true;
692 else
693 csdev->activated = false;
694
695 return size;
696
697}
698static DEVICE_ATTR_RW(enable_sink);
699
700static ssize_t enable_source_show(struct device *dev,
701 struct device_attribute *attr, char *buf)
702{
703 struct coresight_device *csdev = to_coresight_device(dev);
704
Li Pengchenge8dc27d2016-05-03 11:33:35 -0600705 return scnprintf(buf, PAGE_SIZE, "%u\n", csdev->enable);
Pratik Patela06ae862014-11-03 11:07:35 -0700706}
707
708static ssize_t enable_source_store(struct device *dev,
709 struct device_attribute *attr,
710 const char *buf, size_t size)
711{
712 int ret = 0;
713 unsigned long val;
714 struct coresight_device *csdev = to_coresight_device(dev);
715
716 ret = kstrtoul(buf, 10, &val);
717 if (ret)
718 return ret;
719
720 if (val) {
721 ret = coresight_enable(csdev);
722 if (ret)
723 return ret;
724 } else {
725 coresight_disable(csdev);
726 }
727
728 return size;
729}
730static DEVICE_ATTR_RW(enable_source);
731
732static struct attribute *coresight_sink_attrs[] = {
733 &dev_attr_enable_sink.attr,
734 NULL,
735};
736ATTRIBUTE_GROUPS(coresight_sink);
737
738static struct attribute *coresight_source_attrs[] = {
739 &dev_attr_enable_source.attr,
740 NULL,
741};
742ATTRIBUTE_GROUPS(coresight_source);
743
744static struct device_type coresight_dev_type[] = {
745 {
746 .name = "none",
747 },
748 {
749 .name = "sink",
750 .groups = coresight_sink_groups,
751 },
752 {
753 .name = "link",
754 },
755 {
756 .name = "linksink",
757 .groups = coresight_sink_groups,
758 },
759 {
760 .name = "source",
761 .groups = coresight_source_groups,
762 },
763};
764
765static void coresight_device_release(struct device *dev)
766{
767 struct coresight_device *csdev = to_coresight_device(dev);
768
Mathieu Poirierfae54152016-02-02 14:13:57 -0700769 kfree(csdev->conns);
770 kfree(csdev->refcnt);
Pratik Patela06ae862014-11-03 11:07:35 -0700771 kfree(csdev);
772}
773
774static int coresight_orphan_match(struct device *dev, void *data)
775{
776 int i;
777 bool still_orphan = false;
778 struct coresight_device *csdev, *i_csdev;
779 struct coresight_connection *conn;
780
781 csdev = data;
782 i_csdev = to_coresight_device(dev);
783
784 /* No need to check oneself */
785 if (csdev == i_csdev)
786 return 0;
787
788 /* Move on to another component if no connection is orphan */
789 if (!i_csdev->orphan)
790 return 0;
791 /*
792 * Circle throuch all the connection of that component. If we find
793 * an orphan connection whose name matches @csdev, link it.
794 */
Kaixu Xiad786a47d2015-01-26 09:22:20 -0700795 for (i = 0; i < i_csdev->nr_outport; i++) {
Pratik Patela06ae862014-11-03 11:07:35 -0700796 conn = &i_csdev->conns[i];
797
798 /* We have found at least one orphan connection */
799 if (conn->child_dev == NULL) {
800 /* Does it match this newly added device? */
Sudeep Hollab8392152016-08-25 15:18:51 -0600801 if (conn->child_name &&
802 !strcmp(dev_name(&csdev->dev), conn->child_name)) {
Pratik Patela06ae862014-11-03 11:07:35 -0700803 conn->child_dev = csdev;
Kaixu Xia22394bc2015-01-26 09:22:19 -0700804 } else {
805 /* This component still has an orphan */
806 still_orphan = true;
807 }
Pratik Patela06ae862014-11-03 11:07:35 -0700808 }
809 }
810
811 i_csdev->orphan = still_orphan;
812
813 /*
814 * Returning '0' ensures that all known component on the
815 * bus will be checked.
816 */
817 return 0;
818}
819
820static void coresight_fixup_orphan_conns(struct coresight_device *csdev)
821{
822 /*
823 * No need to check for a return value as orphan connection(s)
824 * are hooked-up with each newly added component.
825 */
826 bus_for_each_dev(&coresight_bustype, NULL,
Mathieu Poirierff874222016-02-02 14:13:55 -0700827 csdev, coresight_orphan_match);
Pratik Patela06ae862014-11-03 11:07:35 -0700828}
829
830
831static int coresight_name_match(struct device *dev, void *data)
832{
833 char *to_match;
834 struct coresight_device *i_csdev;
835
836 to_match = data;
837 i_csdev = to_coresight_device(dev);
838
Mathieu Poirierfadf3a42015-12-17 08:47:02 -0700839 if (to_match && !strcmp(to_match, dev_name(&i_csdev->dev)))
Pratik Patela06ae862014-11-03 11:07:35 -0700840 return 1;
841
842 return 0;
843}
844
845static void coresight_fixup_device_conns(struct coresight_device *csdev)
846{
847 int i;
848 struct device *dev = NULL;
849 struct coresight_connection *conn;
850
851 for (i = 0; i < csdev->nr_outport; i++) {
852 conn = &csdev->conns[i];
853 dev = bus_find_device(&coresight_bustype, NULL,
854 (void *)conn->child_name,
855 coresight_name_match);
856
857 if (dev) {
858 conn->child_dev = to_coresight_device(dev);
Mathieu Poirierf2dfab32016-02-02 14:13:58 -0700859 /* and put reference from 'bus_find_device()' */
860 put_device(dev);
Pratik Patela06ae862014-11-03 11:07:35 -0700861 } else {
862 csdev->orphan = true;
863 conn->child_dev = NULL;
864 }
865 }
866}
867
Mathieu Poirierad725ae2016-02-02 14:13:59 -0700868static int coresight_remove_match(struct device *dev, void *data)
869{
870 int i;
871 struct coresight_device *csdev, *iterator;
872 struct coresight_connection *conn;
873
874 csdev = data;
875 iterator = to_coresight_device(dev);
876
877 /* No need to check oneself */
878 if (csdev == iterator)
879 return 0;
880
881 /*
882 * Circle throuch all the connection of that component. If we find
883 * a connection whose name matches @csdev, remove it.
884 */
885 for (i = 0; i < iterator->nr_outport; i++) {
886 conn = &iterator->conns[i];
887
888 if (conn->child_dev == NULL)
889 continue;
890
891 if (!strcmp(dev_name(&csdev->dev), conn->child_name)) {
892 iterator->orphan = true;
893 conn->child_dev = NULL;
894 /* No need to continue */
895 break;
896 }
897 }
898
899 /*
900 * Returning '0' ensures that all known component on the
901 * bus will be checked.
902 */
903 return 0;
904}
905
906static void coresight_remove_conns(struct coresight_device *csdev)
907{
908 bus_for_each_dev(&coresight_bustype, NULL,
909 csdev, coresight_remove_match);
910}
911
Pratik Patela06ae862014-11-03 11:07:35 -0700912/**
913 * coresight_timeout - loop until a bit has changed to a specific state.
914 * @addr: base address of the area of interest.
915 * @offset: address of a register, starting from @addr.
916 * @position: the position of the bit of interest.
917 * @value: the value the bit should have.
918 *
919 * Return: 0 as soon as the bit has taken the desired state or -EAGAIN if
920 * TIMEOUT_US has elapsed, which ever happens first.
921 */
922
923int coresight_timeout(void __iomem *addr, u32 offset, int position, int value)
924{
925 int i;
926 u32 val;
927
928 for (i = TIMEOUT_US; i > 0; i--) {
929 val = __raw_readl(addr + offset);
930 /* waiting on the bit to go from 0 to 1 */
931 if (value) {
932 if (val & BIT(position))
933 return 0;
934 /* waiting on the bit to go from 1 to 0 */
935 } else {
936 if (!(val & BIT(position)))
937 return 0;
938 }
939
940 /*
941 * Delay is arbitrary - the specification doesn't say how long
942 * we are expected to wait. Extra check required to make sure
943 * we don't wait needlessly on the last iteration.
944 */
945 if (i - 1)
946 udelay(1);
947 }
948
949 return -EAGAIN;
950}
951
952struct bus_type coresight_bustype = {
953 .name = "coresight",
954};
955
956static int __init coresight_init(void)
957{
958 return bus_register(&coresight_bustype);
959}
960postcore_initcall(coresight_init);
961
962struct coresight_device *coresight_register(struct coresight_desc *desc)
963{
964 int i;
965 int ret;
966 int link_subtype;
967 int nr_refcnts = 1;
968 atomic_t *refcnts = NULL;
969 struct coresight_device *csdev;
Suzuki K Poulose068c0a52016-08-25 15:18:56 -0600970 struct coresight_connection *conns = NULL;
Pratik Patela06ae862014-11-03 11:07:35 -0700971
972 csdev = kzalloc(sizeof(*csdev), GFP_KERNEL);
973 if (!csdev) {
974 ret = -ENOMEM;
975 goto err_kzalloc_csdev;
976 }
977
978 if (desc->type == CORESIGHT_DEV_TYPE_LINK ||
979 desc->type == CORESIGHT_DEV_TYPE_LINKSINK) {
980 link_subtype = desc->subtype.link_subtype;
981
982 if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG)
983 nr_refcnts = desc->pdata->nr_inport;
984 else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT)
985 nr_refcnts = desc->pdata->nr_outport;
986 }
987
988 refcnts = kcalloc(nr_refcnts, sizeof(*refcnts), GFP_KERNEL);
989 if (!refcnts) {
990 ret = -ENOMEM;
991 goto err_kzalloc_refcnts;
992 }
993
994 csdev->refcnt = refcnts;
995
996 csdev->nr_inport = desc->pdata->nr_inport;
997 csdev->nr_outport = desc->pdata->nr_outport;
Pratik Patela06ae862014-11-03 11:07:35 -0700998
Suzuki K Poulose068c0a52016-08-25 15:18:56 -0600999 /* Initialise connections if there is at least one outport */
1000 if (csdev->nr_outport) {
1001 conns = kcalloc(csdev->nr_outport, sizeof(*conns), GFP_KERNEL);
1002 if (!conns) {
1003 ret = -ENOMEM;
1004 goto err_kzalloc_conns;
1005 }
1006
1007 for (i = 0; i < csdev->nr_outport; i++) {
1008 conns[i].outport = desc->pdata->outports[i];
1009 conns[i].child_name = desc->pdata->child_names[i];
1010 conns[i].child_port = desc->pdata->child_ports[i];
1011 }
Pratik Patela06ae862014-11-03 11:07:35 -07001012 }
1013
1014 csdev->conns = conns;
1015
1016 csdev->type = desc->type;
1017 csdev->subtype = desc->subtype;
1018 csdev->ops = desc->ops;
1019 csdev->orphan = false;
1020
1021 csdev->dev.type = &coresight_dev_type[desc->type];
1022 csdev->dev.groups = desc->groups;
1023 csdev->dev.parent = desc->dev;
1024 csdev->dev.release = coresight_device_release;
1025 csdev->dev.bus = &coresight_bustype;
1026 dev_set_name(&csdev->dev, "%s", desc->pdata->name);
1027
1028 ret = device_register(&csdev->dev);
1029 if (ret)
1030 goto err_device_register;
1031
1032 mutex_lock(&coresight_mutex);
1033
1034 coresight_fixup_device_conns(csdev);
1035 coresight_fixup_orphan_conns(csdev);
1036
1037 mutex_unlock(&coresight_mutex);
1038
1039 return csdev;
1040
1041err_device_register:
1042 kfree(conns);
1043err_kzalloc_conns:
1044 kfree(refcnts);
1045err_kzalloc_refcnts:
1046 kfree(csdev);
1047err_kzalloc_csdev:
1048 return ERR_PTR(ret);
1049}
1050EXPORT_SYMBOL_GPL(coresight_register);
1051
1052void coresight_unregister(struct coresight_device *csdev)
1053{
Mathieu Poirierad725ae2016-02-02 14:13:59 -07001054 /* Remove references of that device in the topology */
1055 coresight_remove_conns(csdev);
Pratik Patela06ae862014-11-03 11:07:35 -07001056 device_unregister(&csdev->dev);
Pratik Patela06ae862014-11-03 11:07:35 -07001057}
1058EXPORT_SYMBOL_GPL(coresight_unregister);