0001
0002
0003
0004
0005
0006 #include <linux/acpi.h>
0007 #include <linux/types.h>
0008 #include <linux/err.h>
0009 #include <linux/slab.h>
0010 #include <linux/clk.h>
0011 #include <linux/of.h>
0012 #include <linux/of_address.h>
0013 #include <linux/of_graph.h>
0014 #include <linux/of_platform.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/amba/bus.h>
0017 #include <linux/coresight.h>
0018 #include <linux/cpumask.h>
0019 #include <asm/smp_plat.h>
0020
0021 #include "coresight-priv.h"
0022
0023
0024
0025
0026 static int coresight_alloc_conns(struct device *dev,
0027 struct coresight_platform_data *pdata)
0028 {
0029 if (pdata->nr_outport) {
0030 pdata->conns = devm_kcalloc(dev, pdata->nr_outport,
0031 sizeof(*pdata->conns), GFP_KERNEL);
0032 if (!pdata->conns)
0033 return -ENOMEM;
0034 }
0035
0036 return 0;
0037 }
0038
0039 static struct device *
0040 coresight_find_device_by_fwnode(struct fwnode_handle *fwnode)
0041 {
0042 struct device *dev = NULL;
0043
0044
0045
0046
0047
0048 dev = bus_find_device_by_fwnode(&platform_bus_type, fwnode);
0049 if (dev)
0050 return dev;
0051
0052
0053
0054
0055
0056 return bus_find_device_by_fwnode(&amba_bustype, fwnode);
0057 }
0058
0059
0060
0061
0062
0063
0064
0065 struct coresight_device *
0066 coresight_find_csdev_by_fwnode(struct fwnode_handle *r_fwnode)
0067 {
0068 struct device *dev;
0069 struct coresight_device *csdev = NULL;
0070
0071 dev = bus_find_device_by_fwnode(&coresight_bustype, r_fwnode);
0072 if (dev) {
0073 csdev = to_coresight_device(dev);
0074 put_device(dev);
0075 }
0076 return csdev;
0077 }
0078 EXPORT_SYMBOL_GPL(coresight_find_csdev_by_fwnode);
0079
0080 #ifdef CONFIG_OF
0081 static inline bool of_coresight_legacy_ep_is_input(struct device_node *ep)
0082 {
0083 return of_property_read_bool(ep, "slave-mode");
0084 }
0085
0086 static void of_coresight_get_ports_legacy(const struct device_node *node,
0087 int *nr_inport, int *nr_outport)
0088 {
0089 struct device_node *ep = NULL;
0090 struct of_endpoint endpoint;
0091 int in = 0, out = 0;
0092
0093
0094
0095
0096
0097 if (!of_graph_is_present(node))
0098 return;
0099 do {
0100 ep = of_graph_get_next_endpoint(node, ep);
0101 if (!ep)
0102 break;
0103
0104 if (of_graph_parse_endpoint(ep, &endpoint))
0105 continue;
0106
0107 if (of_coresight_legacy_ep_is_input(ep)) {
0108 in = (endpoint.port + 1 > in) ?
0109 endpoint.port + 1 : in;
0110 } else {
0111 out = (endpoint.port + 1) > out ?
0112 endpoint.port + 1 : out;
0113 }
0114
0115 } while (ep);
0116
0117 *nr_inport = in;
0118 *nr_outport = out;
0119 }
0120
0121 static struct device_node *of_coresight_get_port_parent(struct device_node *ep)
0122 {
0123 struct device_node *parent = of_graph_get_port_parent(ep);
0124
0125
0126
0127
0128
0129 if (of_node_name_eq(parent, "in-ports") ||
0130 of_node_name_eq(parent, "out-ports"))
0131 parent = of_get_next_parent(parent);
0132
0133 return parent;
0134 }
0135
0136 static inline struct device_node *
0137 of_coresight_get_input_ports_node(const struct device_node *node)
0138 {
0139 return of_get_child_by_name(node, "in-ports");
0140 }
0141
0142 static inline struct device_node *
0143 of_coresight_get_output_ports_node(const struct device_node *node)
0144 {
0145 return of_get_child_by_name(node, "out-ports");
0146 }
0147
0148 static inline int
0149 of_coresight_count_ports(struct device_node *port_parent)
0150 {
0151 int i = 0;
0152 struct device_node *ep = NULL;
0153 struct of_endpoint endpoint;
0154
0155 while ((ep = of_graph_get_next_endpoint(port_parent, ep))) {
0156
0157 if (of_graph_parse_endpoint(ep, &endpoint))
0158 continue;
0159 if (endpoint.port + 1 > i)
0160 i = endpoint.port + 1;
0161 }
0162
0163 return i;
0164 }
0165
0166 static void of_coresight_get_ports(const struct device_node *node,
0167 int *nr_inport, int *nr_outport)
0168 {
0169 struct device_node *input_ports = NULL, *output_ports = NULL;
0170
0171 input_ports = of_coresight_get_input_ports_node(node);
0172 output_ports = of_coresight_get_output_ports_node(node);
0173
0174 if (input_ports || output_ports) {
0175 if (input_ports) {
0176 *nr_inport = of_coresight_count_ports(input_ports);
0177 of_node_put(input_ports);
0178 }
0179 if (output_ports) {
0180 *nr_outport = of_coresight_count_ports(output_ports);
0181 of_node_put(output_ports);
0182 }
0183 } else {
0184
0185 of_coresight_get_ports_legacy(node, nr_inport, nr_outport);
0186 }
0187 }
0188
0189 static int of_coresight_get_cpu(struct device *dev)
0190 {
0191 int cpu;
0192 struct device_node *dn;
0193
0194 if (!dev->of_node)
0195 return -ENODEV;
0196
0197 dn = of_parse_phandle(dev->of_node, "cpu", 0);
0198 if (!dn)
0199 return -ENODEV;
0200
0201 cpu = of_cpu_node_to_id(dn);
0202 of_node_put(dn);
0203
0204 return cpu;
0205 }
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217 static int of_coresight_parse_endpoint(struct device *dev,
0218 struct device_node *ep,
0219 struct coresight_platform_data *pdata)
0220 {
0221 int ret = 0;
0222 struct of_endpoint endpoint, rendpoint;
0223 struct device_node *rparent = NULL;
0224 struct device_node *rep = NULL;
0225 struct device *rdev = NULL;
0226 struct fwnode_handle *rdev_fwnode;
0227 struct coresight_connection *conn;
0228
0229 do {
0230
0231 if (of_graph_parse_endpoint(ep, &endpoint))
0232 break;
0233
0234
0235
0236
0237 rep = of_graph_get_remote_endpoint(ep);
0238 if (!rep)
0239 break;
0240 rparent = of_coresight_get_port_parent(rep);
0241 if (!rparent)
0242 break;
0243 if (of_graph_parse_endpoint(rep, &rendpoint))
0244 break;
0245
0246 rdev_fwnode = of_fwnode_handle(rparent);
0247
0248 rdev = coresight_find_device_by_fwnode(rdev_fwnode);
0249 if (!rdev) {
0250 ret = -EPROBE_DEFER;
0251 break;
0252 }
0253
0254 conn = &pdata->conns[endpoint.port];
0255 if (conn->child_fwnode) {
0256 dev_warn(dev, "Duplicate output port %d\n",
0257 endpoint.port);
0258 ret = -EINVAL;
0259 break;
0260 }
0261 conn->outport = endpoint.port;
0262
0263
0264
0265
0266
0267
0268
0269
0270 conn->child_fwnode = fwnode_handle_get(rdev_fwnode);
0271 conn->child_port = rendpoint.port;
0272
0273 } while (0);
0274
0275 of_node_put(rparent);
0276 of_node_put(rep);
0277 put_device(rdev);
0278
0279 return ret;
0280 }
0281
0282 static int of_get_coresight_platform_data(struct device *dev,
0283 struct coresight_platform_data *pdata)
0284 {
0285 int ret = 0;
0286 struct device_node *ep = NULL;
0287 const struct device_node *parent = NULL;
0288 bool legacy_binding = false;
0289 struct device_node *node = dev->of_node;
0290
0291
0292 of_coresight_get_ports(node, &pdata->nr_inport, &pdata->nr_outport);
0293
0294
0295 if (!pdata->nr_outport)
0296 return 0;
0297
0298 ret = coresight_alloc_conns(dev, pdata);
0299 if (ret)
0300 return ret;
0301
0302 parent = of_coresight_get_output_ports_node(node);
0303
0304
0305
0306
0307
0308 if (!parent) {
0309 legacy_binding = true;
0310 parent = node;
0311 dev_warn_once(dev, "Uses obsolete Coresight DT bindings\n");
0312 }
0313
0314
0315 while ((ep = of_graph_get_next_endpoint(parent, ep))) {
0316
0317
0318
0319
0320
0321
0322 if (legacy_binding && of_coresight_legacy_ep_is_input(ep))
0323 continue;
0324
0325 ret = of_coresight_parse_endpoint(dev, ep, pdata);
0326 if (ret)
0327 return ret;
0328 }
0329
0330 return 0;
0331 }
0332 #else
0333 static inline int
0334 of_get_coresight_platform_data(struct device *dev,
0335 struct coresight_platform_data *pdata)
0336 {
0337 return -ENOENT;
0338 }
0339
0340 static inline int of_coresight_get_cpu(struct device *dev)
0341 {
0342 return -ENODEV;
0343 }
0344 #endif
0345
0346 #ifdef CONFIG_ACPI
0347
0348 #include <acpi/actypes.h>
0349 #include <acpi/processor.h>
0350
0351
0352 static const guid_t acpi_graph_uuid = GUID_INIT(0xab02a46b, 0x74c7, 0x45a2,
0353 0xbd, 0x68, 0xf7, 0xd3,
0354 0x44, 0xef, 0x21, 0x53);
0355
0356 static const guid_t coresight_graph_uuid = GUID_INIT(0x3ecbc8b6, 0x1d0e, 0x4fb3,
0357 0x81, 0x07, 0xe6, 0x27,
0358 0xf8, 0x05, 0xc6, 0xcd);
0359 #define ACPI_CORESIGHT_LINK_SLAVE 0
0360 #define ACPI_CORESIGHT_LINK_MASTER 1
0361
0362 static inline bool is_acpi_guid(const union acpi_object *obj)
0363 {
0364 return (obj->type == ACPI_TYPE_BUFFER) && (obj->buffer.length == 16);
0365 }
0366
0367
0368
0369
0370
0371 static inline bool acpi_guid_matches(const union acpi_object *obj,
0372 const guid_t *guid)
0373 {
0374 return is_acpi_guid(obj) &&
0375 guid_equal((guid_t *)obj->buffer.pointer, guid);
0376 }
0377
0378 static inline bool is_acpi_dsd_graph_guid(const union acpi_object *obj)
0379 {
0380 return acpi_guid_matches(obj, &acpi_graph_uuid);
0381 }
0382
0383 static inline bool is_acpi_coresight_graph_guid(const union acpi_object *obj)
0384 {
0385 return acpi_guid_matches(obj, &coresight_graph_uuid);
0386 }
0387
0388 static inline bool is_acpi_coresight_graph(const union acpi_object *obj)
0389 {
0390 const union acpi_object *graphid, *guid, *links;
0391
0392 if (obj->type != ACPI_TYPE_PACKAGE ||
0393 obj->package.count < 3)
0394 return false;
0395
0396 graphid = &obj->package.elements[0];
0397 guid = &obj->package.elements[1];
0398 links = &obj->package.elements[2];
0399
0400 if (graphid->type != ACPI_TYPE_INTEGER ||
0401 links->type != ACPI_TYPE_INTEGER)
0402 return false;
0403
0404 return is_acpi_coresight_graph_guid(guid);
0405 }
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475 static inline bool acpi_validate_dsd_graph(const union acpi_object *graph)
0476 {
0477 int i, n;
0478 const union acpi_object *rev, *nr_graphs;
0479
0480
0481 if (graph->package.count < 2)
0482 return false;
0483
0484 rev = &graph->package.elements[0];
0485 nr_graphs = &graph->package.elements[1];
0486
0487 if (rev->type != ACPI_TYPE_INTEGER ||
0488 nr_graphs->type != ACPI_TYPE_INTEGER)
0489 return false;
0490
0491
0492 if (rev->integer.value != 0)
0493 return false;
0494
0495 n = nr_graphs->integer.value;
0496
0497 if (n != 1)
0498 return false;
0499
0500
0501 if (graph->package.count != (n + 2))
0502 return false;
0503
0504
0505
0506
0507
0508 for (i = 2; i < n + 2; i++) {
0509 const union acpi_object *obj = &graph->package.elements[i];
0510
0511 if (obj->type != ACPI_TYPE_PACKAGE ||
0512 obj->package.count < 3)
0513 return false;
0514 }
0515
0516 return true;
0517 }
0518
0519
0520 static const union acpi_object *
0521 acpi_get_dsd_graph(struct acpi_device *adev)
0522 {
0523 int i;
0524 struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
0525 acpi_status status;
0526 const union acpi_object *dsd;
0527
0528 status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL,
0529 &buf, ACPI_TYPE_PACKAGE);
0530 if (ACPI_FAILURE(status))
0531 return NULL;
0532
0533 dsd = buf.pointer;
0534
0535
0536
0537
0538
0539 for (i = 0; i + 1 < dsd->package.count; i += 2) {
0540 const union acpi_object *guid, *package;
0541
0542 guid = &dsd->package.elements[i];
0543 package = &dsd->package.elements[i + 1];
0544
0545
0546 if (!is_acpi_guid(guid) || package->type != ACPI_TYPE_PACKAGE)
0547 break;
0548
0549 if (!is_acpi_dsd_graph_guid(guid))
0550 continue;
0551 if (acpi_validate_dsd_graph(package))
0552 return package;
0553
0554 dev_warn(&adev->dev, "Invalid Graph _DSD property\n");
0555 }
0556
0557 return NULL;
0558 }
0559
0560 static inline bool
0561 acpi_validate_coresight_graph(const union acpi_object *cs_graph)
0562 {
0563 int nlinks;
0564
0565 nlinks = cs_graph->package.elements[2].integer.value;
0566
0567
0568
0569
0570 if (cs_graph->package.count != (nlinks + 3))
0571 return false;
0572
0573 return true;
0574 }
0575
0576
0577
0578
0579
0580
0581
0582
0583 static const union acpi_object *
0584 acpi_get_coresight_graph(struct acpi_device *adev)
0585 {
0586 const union acpi_object *graph_list, *graph;
0587 int i, nr_graphs;
0588
0589 graph_list = acpi_get_dsd_graph(adev);
0590 if (!graph_list)
0591 return graph_list;
0592
0593 nr_graphs = graph_list->package.elements[1].integer.value;
0594
0595 for (i = 2; i < nr_graphs + 2; i++) {
0596 graph = &graph_list->package.elements[i];
0597 if (!is_acpi_coresight_graph(graph))
0598 continue;
0599 if (acpi_validate_coresight_graph(graph))
0600 return graph;
0601
0602 break;
0603 }
0604
0605 return NULL;
0606 }
0607
0608
0609
0610
0611
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624
0625 static int acpi_coresight_parse_link(struct acpi_device *adev,
0626 const union acpi_object *link,
0627 struct coresight_connection *conn)
0628 {
0629 int dir;
0630 const union acpi_object *fields;
0631 struct acpi_device *r_adev;
0632 struct device *rdev;
0633
0634 if (link->type != ACPI_TYPE_PACKAGE ||
0635 link->package.count != 4)
0636 return -EINVAL;
0637
0638 fields = link->package.elements;
0639
0640 if (fields[0].type != ACPI_TYPE_INTEGER ||
0641 fields[1].type != ACPI_TYPE_INTEGER ||
0642 fields[2].type != ACPI_TYPE_LOCAL_REFERENCE ||
0643 fields[3].type != ACPI_TYPE_INTEGER)
0644 return -EINVAL;
0645
0646 r_adev = acpi_fetch_acpi_dev(fields[2].reference.handle);
0647 if (!r_adev)
0648 return -ENODEV;
0649
0650 dir = fields[3].integer.value;
0651 if (dir == ACPI_CORESIGHT_LINK_MASTER) {
0652 conn->outport = fields[0].integer.value;
0653 conn->child_port = fields[1].integer.value;
0654 rdev = coresight_find_device_by_fwnode(&r_adev->fwnode);
0655 if (!rdev)
0656 return -EPROBE_DEFER;
0657
0658
0659
0660
0661
0662
0663
0664
0665 conn->child_fwnode = fwnode_handle_get(&r_adev->fwnode);
0666 } else if (dir == ACPI_CORESIGHT_LINK_SLAVE) {
0667
0668
0669
0670
0671
0672 conn->child_port = fields[0].integer.value;
0673 } else {
0674
0675 return -EINVAL;
0676 }
0677
0678 return dir;
0679 }
0680
0681
0682
0683
0684
0685
0686 static int acpi_coresight_parse_graph(struct acpi_device *adev,
0687 struct coresight_platform_data *pdata)
0688 {
0689 int rc, i, nlinks;
0690 const union acpi_object *graph;
0691 struct coresight_connection *conns, *ptr;
0692
0693 pdata->nr_inport = pdata->nr_outport = 0;
0694 graph = acpi_get_coresight_graph(adev);
0695 if (!graph)
0696 return -ENOENT;
0697
0698 nlinks = graph->package.elements[2].integer.value;
0699 if (!nlinks)
0700 return 0;
0701
0702
0703
0704
0705
0706
0707
0708 conns = devm_kcalloc(&adev->dev, nlinks, sizeof(*conns), GFP_KERNEL);
0709 if (!conns)
0710 return -ENOMEM;
0711 ptr = conns;
0712 for (i = 0; i < nlinks; i++) {
0713 const union acpi_object *link = &graph->package.elements[3 + i];
0714 int dir;
0715
0716 dir = acpi_coresight_parse_link(adev, link, ptr);
0717 if (dir < 0)
0718 return dir;
0719
0720 if (dir == ACPI_CORESIGHT_LINK_MASTER) {
0721 if (ptr->outport >= pdata->nr_outport)
0722 pdata->nr_outport = ptr->outport + 1;
0723 ptr++;
0724 } else {
0725 WARN_ON(pdata->nr_inport == ptr->child_port + 1);
0726
0727
0728
0729
0730
0731
0732
0733 if (ptr->child_port >= pdata->nr_inport)
0734 pdata->nr_inport = ptr->child_port + 1;
0735 }
0736 }
0737
0738 rc = coresight_alloc_conns(&adev->dev, pdata);
0739 if (rc)
0740 return rc;
0741
0742
0743 for (i = 0; conns + i < ptr; i++) {
0744 int port = conns[i].outport;
0745
0746
0747 WARN_ON(pdata->conns[port].child_fwnode);
0748 pdata->conns[port] = conns[i];
0749 }
0750
0751 devm_kfree(&adev->dev, conns);
0752 return 0;
0753 }
0754
0755
0756
0757
0758
0759
0760
0761 static int
0762 acpi_handle_to_logical_cpuid(acpi_handle handle)
0763 {
0764 int i;
0765 struct acpi_processor *pr;
0766
0767 for_each_possible_cpu(i) {
0768 pr = per_cpu(processors, i);
0769 if (pr && pr->handle == handle)
0770 break;
0771 }
0772
0773 return i;
0774 }
0775
0776
0777
0778
0779
0780
0781
0782
0783 static int acpi_coresight_get_cpu(struct device *dev)
0784 {
0785 int cpu;
0786 acpi_handle cpu_handle;
0787 acpi_status status;
0788 struct acpi_device *adev = ACPI_COMPANION(dev);
0789
0790 if (!adev)
0791 return -ENODEV;
0792 status = acpi_get_parent(adev->handle, &cpu_handle);
0793 if (ACPI_FAILURE(status))
0794 return -ENODEV;
0795
0796 cpu = acpi_handle_to_logical_cpuid(cpu_handle);
0797 if (cpu >= nr_cpu_ids)
0798 return -ENODEV;
0799 return cpu;
0800 }
0801
0802 static int
0803 acpi_get_coresight_platform_data(struct device *dev,
0804 struct coresight_platform_data *pdata)
0805 {
0806 struct acpi_device *adev;
0807
0808 adev = ACPI_COMPANION(dev);
0809 if (!adev)
0810 return -EINVAL;
0811
0812 return acpi_coresight_parse_graph(adev, pdata);
0813 }
0814
0815 #else
0816
0817 static inline int
0818 acpi_get_coresight_platform_data(struct device *dev,
0819 struct coresight_platform_data *pdata)
0820 {
0821 return -ENOENT;
0822 }
0823
0824 static inline int acpi_coresight_get_cpu(struct device *dev)
0825 {
0826 return -ENODEV;
0827 }
0828 #endif
0829
0830 int coresight_get_cpu(struct device *dev)
0831 {
0832 if (is_of_node(dev->fwnode))
0833 return of_coresight_get_cpu(dev);
0834 else if (is_acpi_device_node(dev->fwnode))
0835 return acpi_coresight_get_cpu(dev);
0836 return 0;
0837 }
0838 EXPORT_SYMBOL_GPL(coresight_get_cpu);
0839
0840 struct coresight_platform_data *
0841 coresight_get_platform_data(struct device *dev)
0842 {
0843 int ret = -ENOENT;
0844 struct coresight_platform_data *pdata = NULL;
0845 struct fwnode_handle *fwnode = dev_fwnode(dev);
0846
0847 if (IS_ERR_OR_NULL(fwnode))
0848 goto error;
0849
0850 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
0851 if (!pdata) {
0852 ret = -ENOMEM;
0853 goto error;
0854 }
0855
0856 if (is_of_node(fwnode))
0857 ret = of_get_coresight_platform_data(dev, pdata);
0858 else if (is_acpi_device_node(fwnode))
0859 ret = acpi_get_coresight_platform_data(dev, pdata);
0860
0861 if (!ret)
0862 return pdata;
0863 error:
0864 if (!IS_ERR_OR_NULL(pdata))
0865
0866 coresight_release_platform_data(NULL, pdata);
0867 return ERR_PTR(ret);
0868 }
0869 EXPORT_SYMBOL_GPL(coresight_get_platform_data);