1/* 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> 14#include <linux/module.h> 15#include <linux/init.h> 16#include <linux/types.h> 17#include <linux/device.h> 18#include <linux/io.h> 19#include <linux/err.h> 20#include <linux/export.h> 21#include <linux/slab.h> 22#include <linux/mutex.h> 23#include <linux/clk.h> 24#include <linux/coresight.h> 25#include <linux/of_platform.h> 26#include <linux/delay.h> 27 28#include "coresight-priv.h" 29 30static DEFINE_MUTEX(coresight_mutex); 31 32static int coresight_id_match(struct device *dev, void *data) 33{ 34 int trace_id, i_trace_id; 35 struct coresight_device *csdev, *i_csdev; 36 37 csdev = data; 38 i_csdev = to_coresight_device(dev); 39 40 /* 41 * No need to care about oneself and components that are not 42 * sources or not enabled 43 */ 44 if (i_csdev == csdev || !i_csdev->enable || 45 i_csdev->type != CORESIGHT_DEV_TYPE_SOURCE) 46 return 0; 47 48 /* Get the source ID for both compoment */ 49 trace_id = source_ops(csdev)->trace_id(csdev); 50 i_trace_id = source_ops(i_csdev)->trace_id(i_csdev); 51 52 /* All you need is one */ 53 if (trace_id == i_trace_id) 54 return 1; 55 56 return 0; 57} 58 59static int coresight_source_is_unique(struct coresight_device *csdev) 60{ 61 int trace_id = source_ops(csdev)->trace_id(csdev); 62 63 /* this shouldn't happen */ 64 if (trace_id < 0) 65 return 0; 66 67 return !bus_for_each_dev(&coresight_bustype, NULL, 68 csdev, coresight_id_match); 69} 70 71static int coresight_find_link_inport(struct coresight_device *csdev) 72{ 73 int i; 74 struct coresight_device *parent; 75 struct coresight_connection *conn; 76 77 parent = container_of(csdev->path_link.next, 78 struct coresight_device, path_link); 79 80 for (i = 0; i < parent->nr_outport; i++) { 81 conn = &parent->conns[i]; 82 if (conn->child_dev == csdev) 83 return conn->child_port; 84 } 85 86 dev_err(&csdev->dev, "couldn't find inport, parent: %s, child: %s\n", 87 dev_name(&parent->dev), dev_name(&csdev->dev)); 88 89 return 0; 90} 91 92static int coresight_find_link_outport(struct coresight_device *csdev) 93{ 94 int i; 95 struct coresight_device *child; 96 struct coresight_connection *conn; 97 98 child = container_of(csdev->path_link.prev, 99 struct coresight_device, path_link); 100 101 for (i = 0; i < csdev->nr_outport; i++) { 102 conn = &csdev->conns[i]; 103 if (conn->child_dev == child) 104 return conn->outport; 105 } 106 107 dev_err(&csdev->dev, "couldn't find outport, parent: %s, child: %s\n", 108 dev_name(&csdev->dev), dev_name(&child->dev)); 109 110 return 0; 111} 112 113static int coresight_enable_sink(struct coresight_device *csdev) 114{ 115 int ret; 116 117 if (!csdev->enable) { 118 if (sink_ops(csdev)->enable) { 119 ret = sink_ops(csdev)->enable(csdev); 120 if (ret) 121 return ret; 122 } 123 csdev->enable = true; 124 } 125 126 atomic_inc(csdev->refcnt); 127 128 return 0; 129} 130 131static void coresight_disable_sink(struct coresight_device *csdev) 132{ 133 if (atomic_dec_return(csdev->refcnt) == 0) { 134 if (sink_ops(csdev)->disable) { 135 sink_ops(csdev)->disable(csdev); 136 csdev->enable = false; 137 } 138 } 139} 140 141static int coresight_enable_link(struct coresight_device *csdev) 142{ 143 int ret; 144 int link_subtype; 145 int refport, inport, outport; 146 147 inport = coresight_find_link_inport(csdev); 148 outport = coresight_find_link_outport(csdev); 149 link_subtype = csdev->subtype.link_subtype; 150 151 if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG) 152 refport = inport; 153 else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT) 154 refport = outport; 155 else 156 refport = 0; 157 158 if (atomic_inc_return(&csdev->refcnt[refport]) == 1) { 159 if (link_ops(csdev)->enable) { 160 ret = link_ops(csdev)->enable(csdev, inport, outport); 161 if (ret) 162 return ret; 163 } 164 } 165 166 csdev->enable = true; 167 168 return 0; 169} 170 171static void coresight_disable_link(struct coresight_device *csdev) 172{ 173 int i, nr_conns; 174 int link_subtype; 175 int refport, inport, outport; 176 177 inport = coresight_find_link_inport(csdev); 178 outport = coresight_find_link_outport(csdev); 179 link_subtype = csdev->subtype.link_subtype; 180 181 if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG) { 182 refport = inport; 183 nr_conns = csdev->nr_inport; 184 } else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT) { 185 refport = outport; 186 nr_conns = csdev->nr_outport; 187 } else { 188 refport = 0; 189 nr_conns = 1; 190 } 191 192 if (atomic_dec_return(&csdev->refcnt[refport]) == 0) { 193 if (link_ops(csdev)->disable) 194 link_ops(csdev)->disable(csdev, inport, outport); 195 } 196 197 for (i = 0; i < nr_conns; i++) 198 if (atomic_read(&csdev->refcnt[i]) != 0) 199 return; 200 201 csdev->enable = false; 202} 203 204static int coresight_enable_source(struct coresight_device *csdev) 205{ 206 int ret; 207 208 if (!coresight_source_is_unique(csdev)) { 209 dev_warn(&csdev->dev, "traceID %d not unique\n", 210 source_ops(csdev)->trace_id(csdev)); 211 return -EINVAL; 212 } 213 214 if (!csdev->enable) { 215 if (source_ops(csdev)->enable) { 216 ret = source_ops(csdev)->enable(csdev); 217 if (ret) 218 return ret; 219 } 220 csdev->enable = true; 221 } 222 223 atomic_inc(csdev->refcnt); 224 225 return 0; 226} 227 228static void coresight_disable_source(struct coresight_device *csdev) 229{ 230 if (atomic_dec_return(csdev->refcnt) == 0) { 231 if (source_ops(csdev)->disable) { 232 source_ops(csdev)->disable(csdev); 233 csdev->enable = false; 234 } 235 } 236} 237 238static int coresight_enable_path(struct list_head *path) 239{ 240 int ret = 0; 241 struct coresight_device *cd; 242 243 list_for_each_entry(cd, path, path_link) { 244 if (cd == list_first_entry(path, struct coresight_device, 245 path_link)) { 246 ret = coresight_enable_sink(cd); 247 } else if (list_is_last(&cd->path_link, path)) { 248 /* 249 * Don't enable the source just yet - this needs to 250 * happen at the very end when all links and sink 251 * along the path have been configured properly. 252 */ 253 ; 254 } else { 255 ret = coresight_enable_link(cd); 256 } 257 if (ret) 258 goto err; 259 } 260 261 return 0; 262err: 263 list_for_each_entry_continue_reverse(cd, path, path_link) { 264 if (cd == list_first_entry(path, struct coresight_device, 265 path_link)) { 266 coresight_disable_sink(cd); 267 } else if (list_is_last(&cd->path_link, path)) { 268 ; 269 } else { 270 coresight_disable_link(cd); 271 } 272 } 273 274 return ret; 275} 276 277static int coresight_disable_path(struct list_head *path) 278{ 279 struct coresight_device *cd; 280 281 list_for_each_entry_reverse(cd, path, path_link) { 282 if (cd == list_first_entry(path, struct coresight_device, 283 path_link)) { 284 coresight_disable_sink(cd); 285 } else if (list_is_last(&cd->path_link, path)) { 286 /* 287 * The source has already been stopped, no need 288 * to do it again here. 289 */ 290 ; 291 } else { 292 coresight_disable_link(cd); 293 } 294 } 295 296 return 0; 297} 298 299static int coresight_build_paths(struct coresight_device *csdev, 300 struct list_head *path, 301 bool enable) 302{ 303 int i, ret = -EINVAL; 304 struct coresight_connection *conn; 305 306 list_add(&csdev->path_link, path); 307 308 if ((csdev->type == CORESIGHT_DEV_TYPE_SINK || 309 csdev->type == CORESIGHT_DEV_TYPE_LINKSINK) && 310 csdev->activated) { 311 if (enable) 312 ret = coresight_enable_path(path); 313 else 314 ret = coresight_disable_path(path); 315 } else { 316 for (i = 0; i < csdev->nr_outport; i++) { 317 conn = &csdev->conns[i]; 318 if (coresight_build_paths(conn->child_dev, 319 path, enable) == 0) 320 ret = 0; 321 } 322 } 323 324 if (list_first_entry(path, struct coresight_device, path_link) != csdev) 325 dev_err(&csdev->dev, "wrong device in %s\n", __func__); 326 327 list_del(&csdev->path_link); 328 329 return ret; 330} 331 332int coresight_enable(struct coresight_device *csdev) 333{ 334 int ret = 0; 335 LIST_HEAD(path); 336 337 mutex_lock(&coresight_mutex); 338 if (csdev->type != CORESIGHT_DEV_TYPE_SOURCE) { 339 ret = -EINVAL; 340 dev_err(&csdev->dev, "wrong device type in %s\n", __func__); 341 goto out; 342 } 343 if (csdev->enable) 344 goto out; 345 346 if (coresight_build_paths(csdev, &path, true)) { 347 dev_err(&csdev->dev, "building path(s) failed\n"); 348 goto out; 349 } 350 351 if (coresight_enable_source(csdev)) 352 dev_err(&csdev->dev, "source enable failed\n"); 353out: 354 mutex_unlock(&coresight_mutex); 355 return ret; 356} 357EXPORT_SYMBOL_GPL(coresight_enable); 358 359void coresight_disable(struct coresight_device *csdev) 360{ 361 LIST_HEAD(path); 362 363 mutex_lock(&coresight_mutex); 364 if (csdev->type != CORESIGHT_DEV_TYPE_SOURCE) { 365 dev_err(&csdev->dev, "wrong device type in %s\n", __func__); 366 goto out; 367 } 368 if (!csdev->enable) 369 goto out; 370 371 coresight_disable_source(csdev); 372 if (coresight_build_paths(csdev, &path, false)) 373 dev_err(&csdev->dev, "releasing path(s) failed\n"); 374 375out: 376 mutex_unlock(&coresight_mutex); 377} 378EXPORT_SYMBOL_GPL(coresight_disable); 379 380static ssize_t enable_sink_show(struct device *dev, 381 struct device_attribute *attr, char *buf) 382{ 383 struct coresight_device *csdev = to_coresight_device(dev); 384 385 return scnprintf(buf, PAGE_SIZE, "%u\n", (unsigned)csdev->activated); 386} 387 388static ssize_t enable_sink_store(struct device *dev, 389 struct device_attribute *attr, 390 const char *buf, size_t size) 391{ 392 int ret; 393 unsigned long val; 394 struct coresight_device *csdev = to_coresight_device(dev); 395 396 ret = kstrtoul(buf, 10, &val); 397 if (ret) 398 return ret; 399 400 if (val) 401 csdev->activated = true; 402 else 403 csdev->activated = false; 404 405 return size; 406 407} 408static DEVICE_ATTR_RW(enable_sink); 409 410static ssize_t enable_source_show(struct device *dev, 411 struct device_attribute *attr, char *buf) 412{ 413 struct coresight_device *csdev = to_coresight_device(dev); 414 415 return scnprintf(buf, PAGE_SIZE, "%u\n", (unsigned)csdev->enable); 416} 417 418static ssize_t enable_source_store(struct device *dev, 419 struct device_attribute *attr, 420 const char *buf, size_t size) 421{ 422 int ret = 0; 423 unsigned long val; 424 struct coresight_device *csdev = to_coresight_device(dev); 425 426 ret = kstrtoul(buf, 10, &val); 427 if (ret) 428 return ret; 429 430 if (val) { 431 ret = coresight_enable(csdev); 432 if (ret) 433 return ret; 434 } else { 435 coresight_disable(csdev); 436 } 437 438 return size; 439} 440static DEVICE_ATTR_RW(enable_source); 441 442static struct attribute *coresight_sink_attrs[] = { 443 &dev_attr_enable_sink.attr, 444 NULL, 445}; 446ATTRIBUTE_GROUPS(coresight_sink); 447 448static struct attribute *coresight_source_attrs[] = { 449 &dev_attr_enable_source.attr, 450 NULL, 451}; 452ATTRIBUTE_GROUPS(coresight_source); 453 454static struct device_type coresight_dev_type[] = { 455 { 456 .name = "none", 457 }, 458 { 459 .name = "sink", 460 .groups = coresight_sink_groups, 461 }, 462 { 463 .name = "link", 464 }, 465 { 466 .name = "linksink", 467 .groups = coresight_sink_groups, 468 }, 469 { 470 .name = "source", 471 .groups = coresight_source_groups, 472 }, 473}; 474 475static void coresight_device_release(struct device *dev) 476{ 477 struct coresight_device *csdev = to_coresight_device(dev); 478 479 kfree(csdev); 480} 481 482static int coresight_orphan_match(struct device *dev, void *data) 483{ 484 int i; 485 bool still_orphan = false; 486 struct coresight_device *csdev, *i_csdev; 487 struct coresight_connection *conn; 488 489 csdev = data; 490 i_csdev = to_coresight_device(dev); 491 492 /* No need to check oneself */ 493 if (csdev == i_csdev) 494 return 0; 495 496 /* Move on to another component if no connection is orphan */ 497 if (!i_csdev->orphan) 498 return 0; 499 /* 500 * Circle throuch all the connection of that component. If we find 501 * an orphan connection whose name matches @csdev, link it. 502 */ 503 for (i = 0; i < i_csdev->nr_outport; i++) { 504 conn = &i_csdev->conns[i]; 505 506 /* We have found at least one orphan connection */ 507 if (conn->child_dev == NULL) { 508 /* Does it match this newly added device? */ 509 if (!strcmp(dev_name(&csdev->dev), conn->child_name)) { 510 conn->child_dev = csdev; 511 } else { 512 /* This component still has an orphan */ 513 still_orphan = true; 514 } 515 } 516 } 517 518 i_csdev->orphan = still_orphan; 519 520 /* 521 * Returning '0' ensures that all known component on the 522 * bus will be checked. 523 */ 524 return 0; 525} 526 527static void coresight_fixup_orphan_conns(struct coresight_device *csdev) 528{ 529 /* 530 * No need to check for a return value as orphan connection(s) 531 * are hooked-up with each newly added component. 532 */ 533 bus_for_each_dev(&coresight_bustype, NULL, 534 csdev, coresight_orphan_match); 535} 536 537 538static int coresight_name_match(struct device *dev, void *data) 539{ 540 char *to_match; 541 struct coresight_device *i_csdev; 542 543 to_match = data; 544 i_csdev = to_coresight_device(dev); 545 546 if (to_match && !strcmp(to_match, dev_name(&i_csdev->dev))) 547 return 1; 548 549 return 0; 550} 551 552static void coresight_fixup_device_conns(struct coresight_device *csdev) 553{ 554 int i; 555 struct device *dev = NULL; 556 struct coresight_connection *conn; 557 558 for (i = 0; i < csdev->nr_outport; i++) { 559 conn = &csdev->conns[i]; 560 dev = bus_find_device(&coresight_bustype, NULL, 561 (void *)conn->child_name, 562 coresight_name_match); 563 564 if (dev) { 565 conn->child_dev = to_coresight_device(dev); 566 } else { 567 csdev->orphan = true; 568 conn->child_dev = NULL; 569 } 570 } 571} 572 573/** 574 * coresight_timeout - loop until a bit has changed to a specific state. 575 * @addr: base address of the area of interest. 576 * @offset: address of a register, starting from @addr. 577 * @position: the position of the bit of interest. 578 * @value: the value the bit should have. 579 * 580 * Return: 0 as soon as the bit has taken the desired state or -EAGAIN if 581 * TIMEOUT_US has elapsed, which ever happens first. 582 */ 583 584int coresight_timeout(void __iomem *addr, u32 offset, int position, int value) 585{ 586 int i; 587 u32 val; 588 589 for (i = TIMEOUT_US; i > 0; i--) { 590 val = __raw_readl(addr + offset); 591 /* waiting on the bit to go from 0 to 1 */ 592 if (value) { 593 if (val & BIT(position)) 594 return 0; 595 /* waiting on the bit to go from 1 to 0 */ 596 } else { 597 if (!(val & BIT(position))) 598 return 0; 599 } 600 601 /* 602 * Delay is arbitrary - the specification doesn't say how long 603 * we are expected to wait. Extra check required to make sure 604 * we don't wait needlessly on the last iteration. 605 */ 606 if (i - 1) 607 udelay(1); 608 } 609 610 return -EAGAIN; 611} 612 613struct bus_type coresight_bustype = { 614 .name = "coresight", 615}; 616 617static int __init coresight_init(void) 618{ 619 return bus_register(&coresight_bustype); 620} 621postcore_initcall(coresight_init); 622 623struct coresight_device *coresight_register(struct coresight_desc *desc) 624{ 625 int i; 626 int ret; 627 int link_subtype; 628 int nr_refcnts = 1; 629 atomic_t *refcnts = NULL; 630 struct coresight_device *csdev; 631 struct coresight_connection *conns; 632 633 csdev = kzalloc(sizeof(*csdev), GFP_KERNEL); 634 if (!csdev) { 635 ret = -ENOMEM; 636 goto err_kzalloc_csdev; 637 } 638 639 if (desc->type == CORESIGHT_DEV_TYPE_LINK || 640 desc->type == CORESIGHT_DEV_TYPE_LINKSINK) { 641 link_subtype = desc->subtype.link_subtype; 642 643 if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG) 644 nr_refcnts = desc->pdata->nr_inport; 645 else if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_SPLIT) 646 nr_refcnts = desc->pdata->nr_outport; 647 } 648 649 refcnts = kcalloc(nr_refcnts, sizeof(*refcnts), GFP_KERNEL); 650 if (!refcnts) { 651 ret = -ENOMEM; 652 goto err_kzalloc_refcnts; 653 } 654 655 csdev->refcnt = refcnts; 656 657 csdev->nr_inport = desc->pdata->nr_inport; 658 csdev->nr_outport = desc->pdata->nr_outport; 659 conns = kcalloc(csdev->nr_outport, sizeof(*conns), GFP_KERNEL); 660 if (!conns) { 661 ret = -ENOMEM; 662 goto err_kzalloc_conns; 663 } 664 665 for (i = 0; i < csdev->nr_outport; i++) { 666 conns[i].outport = desc->pdata->outports[i]; 667 conns[i].child_name = desc->pdata->child_names[i]; 668 conns[i].child_port = desc->pdata->child_ports[i]; 669 } 670 671 csdev->conns = conns; 672 673 csdev->type = desc->type; 674 csdev->subtype = desc->subtype; 675 csdev->ops = desc->ops; 676 csdev->orphan = false; 677 678 csdev->dev.type = &coresight_dev_type[desc->type]; 679 csdev->dev.groups = desc->groups; 680 csdev->dev.parent = desc->dev; 681 csdev->dev.release = coresight_device_release; 682 csdev->dev.bus = &coresight_bustype; 683 dev_set_name(&csdev->dev, "%s", desc->pdata->name); 684 685 ret = device_register(&csdev->dev); 686 if (ret) 687 goto err_device_register; 688 689 mutex_lock(&coresight_mutex); 690 691 coresight_fixup_device_conns(csdev); 692 coresight_fixup_orphan_conns(csdev); 693 694 mutex_unlock(&coresight_mutex); 695 696 return csdev; 697 698err_device_register: 699 kfree(conns); 700err_kzalloc_conns: 701 kfree(refcnts); 702err_kzalloc_refcnts: 703 kfree(csdev); 704err_kzalloc_csdev: 705 return ERR_PTR(ret); 706} 707EXPORT_SYMBOL_GPL(coresight_register); 708 709void coresight_unregister(struct coresight_device *csdev) 710{ 711 mutex_lock(&coresight_mutex); 712 713 kfree(csdev->conns); 714 device_unregister(&csdev->dev); 715 716 mutex_unlock(&coresight_mutex); 717} 718EXPORT_SYMBOL_GPL(coresight_unregister); 719 720MODULE_LICENSE("GPL v2"); 721