Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'coresight-next-v6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/coresight/linux into char-misc-next

Suzuki writes:

coresight: hwtracing subsystem updates for v6.10

CoreSight/hwtracing updates for the next release includes:
- ACPI power management support for CoreSight legacy components, via migration
from AMBA to platform device
- Fixes for ETE register save/restore during CPU Idle.
- ACPI support TMC for Scatter-Gather mode.
- his_ptt driver update to set the parent device for PMU and documentation fixes
- Qcomm Trace component DT binding fixes
- Miscellaneous cleanups

Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>

* tag 'coresight-next-v6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/coresight/linux: (28 commits)
hwtracing: hisi_ptt: Assign parent for event_source device
Documentation: ABI + trace: hisi_ptt: update paths to bus/event_source
coresight: tmc: Enable SG capability on ACPI based SoC-400 TMC ETR devices
coresight: Docs/ABI/testing/sysfs-bus-coresight-devices: Fix spelling errors
coresight: tpiu: Convert to platform remove callback returning void
coresight: tmc: Convert to platform remove callback returning void
coresight: stm: Convert to platform remove callback returning void
coresight: debug: Convert to platform remove callback returning void
coresight: catu: Convert to platform remove callback returning void
coresight: Remove duplicate linux/amba/bus.h header
coresight: stm: Remove duplicate linux/acpi.h header
coresight: etm4x: Fix access to resource selector registers
coresight: etm4x: Safe access for TRCQCLTR
coresight: etm4x: Do not save/restore Data trace control registers
coresight: etm4x: Do not hardcode IOMEM access for register restore
coresight: debug: Move ACPI support from AMBA driver to platform driver
coresight: stm: Move ACPI support from AMBA driver to platform driver
coresight: tmc: Move ACPI support from AMBA driver to platform driver
coresight: tpiu: Move ACPI support from AMBA driver to platform driver
coresight: catu: Move ACPI support from AMBA driver to platform driver
...

+793 -240
+1 -1
Documentation/ABI/testing/sysfs-bus-coresight-devices-etm3x
··· 22 22 Description: (RW) Used in conjunction with @addr_idx. Specifies 23 23 characteristics about the address comparator being configure, 24 24 for example the access type, the kind of instruction to trace, 25 - processor contect ID to trigger on, etc. Individual fields in 25 + processor context ID to trigger on, etc. Individual fields in 26 26 the access type register may vary on the version of the trace 27 27 entity. 28 28
+1 -1
Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc
··· 97 97 KernelVersion: 6.7 98 98 Contact: Anshuman Khandual <anshuman.khandual@arm.com> 99 99 Description: (Read) Shows all supported Coresight TMC-ETR buffer modes available 100 - for the users to configure explicitly. This file is avaialble only 100 + for the users to configure explicitly. This file is available only 101 101 for TMC ETR devices. 102 102 103 103 What: /sys/bus/coresight/devices/<memory_map>.tmc/buf_mode_preferred
+1 -1
Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
··· 244 244 Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com> 245 245 Description: 246 246 (RW) Read or write the status of timestamp upon all interface. 247 - Only value 0 and 1 can be written to this node. Set this node to 1 to requeset 247 + Only value 0 and 1 can be written to this node. Set this node to 1 to request 248 248 timestamp to all trace packet. 249 249 Accepts only one of the 2 values - 0 or 1. 250 250 0 : Disable the timestamp of all trace packets.
+6 -6
Documentation/ABI/testing/sysfs-devices-hisi_ptt Documentation/ABI/testing/sysfs-bus-event_source-devices-hisi_ptt
··· 1 - What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune 1 + What: /sys/bus/event_source/devices/hisi_ptt<sicl_id>_<core_id>/tune 2 2 Date: October 2022 3 3 KernelVersion: 6.1 4 4 Contact: Yicong Yang <yangyicong@hisilicon.com> ··· 8 8 9 9 See Documentation/trace/hisi-ptt.rst for more information. 10 10 11 - What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune/qos_tx_cpl 11 + What: /sys/bus/event_source/devices/hisi_ptt<sicl_id>_<core_id>/tune/qos_tx_cpl 12 12 Date: October 2022 13 13 KernelVersion: 6.1 14 14 Contact: Yicong Yang <yangyicong@hisilicon.com> ··· 18 18 will return an error, and out of range values will be converted 19 19 to 2. The value indicates a probable level of the event. 20 20 21 - What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune/qos_tx_np 21 + What: /sys/bus/event_source/devices/hisi_ptt<sicl_id>_<core_id>/tune/qos_tx_np 22 22 Date: October 2022 23 23 KernelVersion: 6.1 24 24 Contact: Yicong Yang <yangyicong@hisilicon.com> ··· 28 28 will return an error, and out of range values will be converted 29 29 to 2. The value indicates a probable level of the event. 30 30 31 - What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune/qos_tx_p 31 + What: /sys/bus/event_source/devices/hisi_ptt<sicl_id>_<core_id>/tune/qos_tx_p 32 32 Date: October 2022 33 33 KernelVersion: 6.1 34 34 Contact: Yicong Yang <yangyicong@hisilicon.com> ··· 38 38 will return an error, and out of range values will be converted 39 39 to 2. The value indicates a probable level of the event. 40 40 41 - What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune/rx_alloc_buf_level 41 + What: /sys/bus/event_source/devices/hisi_ptt<sicl_id>_<core_id>/tune/rx_alloc_buf_level 42 42 Date: October 2022 43 43 KernelVersion: 6.1 44 44 Contact: Yicong Yang <yangyicong@hisilicon.com> ··· 49 49 will return an error, and out of range values will be converted 50 50 to 2. The value indicates a probable level of the event. 51 51 52 - What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune/tx_alloc_buf_level 52 + What: /sys/bus/event_source/devices/hisi_ptt<sicl_id>_<core_id>/tune/tx_alloc_buf_level 53 53 Date: October 2022 54 54 KernelVersion: 6.1 55 55 Contact: Yicong Yang <yangyicong@hisilicon.com>
+15 -19
Documentation/devicetree/bindings/arm/qcom,coresight-tpda.yaml
··· 66 66 - const: apb_pclk 67 67 68 68 in-ports: 69 - type: object 70 69 description: | 71 70 Input connections from TPDM to TPDA 72 71 $ref: /schemas/graph.yaml#/properties/ports 73 72 74 73 out-ports: 75 - type: object 76 74 description: | 77 75 Output connections from the TPDA to legacy CoreSight trace bus. 78 76 $ref: /schemas/graph.yaml#/properties/ports ··· 95 97 # minimum tpda definition. 96 98 - | 97 99 tpda@6004000 { 98 - compatible = "qcom,coresight-tpda", "arm,primecell"; 99 - reg = <0x6004000 0x1000>; 100 + compatible = "qcom,coresight-tpda", "arm,primecell"; 101 + reg = <0x6004000 0x1000>; 100 102 101 - clocks = <&aoss_qmp>; 102 - clock-names = "apb_pclk"; 103 + clocks = <&aoss_qmp>; 104 + clock-names = "apb_pclk"; 103 105 104 - in-ports { 105 - #address-cells = <1>; 106 - #size-cells = <0>; 106 + in-ports { 107 + #address-cells = <1>; 108 + #size-cells = <0>; 107 109 108 110 port@0 { 109 111 reg = <0>; 110 112 tpda_qdss_0_in_tpdm_dcc: endpoint { 111 - remote-endpoint = 112 - <&tpdm_dcc_out_tpda_qdss_0>; 113 - }; 113 + remote-endpoint = <&tpdm_dcc_out_tpda_qdss_0>; 114 + }; 114 115 }; 115 116 }; 116 117 117 - out-ports { 118 - port { 119 - tpda_qdss_out_funnel_in0: endpoint { 120 - remote-endpoint = 121 - <&funnel_in0_in_tpda_qdss>; 122 - }; 118 + out-ports { 119 + port { 120 + tpda_qdss_out_funnel_in0: endpoint { 121 + remote-endpoint = <&funnel_in0_in_tpda_qdss>; 123 122 }; 124 - }; 123 + }; 124 + }; 125 125 }; 126 126 127 127 ...
+2 -2
Documentation/trace/hisi-ptt.rst
··· 40 40 Complex for each SICL. 41 41 :: 42 42 43 - /sys/devices/hisi_ptt<sicl_id>_<core_id> 43 + /sys/bus/event_source/devices/hisi_ptt<sicl_id>_<core_id> 44 44 45 45 Tune 46 46 ==== ··· 53 53 a simple open/read/write/close cycle will be used to tune the event. 54 54 :: 55 55 56 - $ cd /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune 56 + $ cd /sys/bus/event_source/devices/hisi_ptt<sicl_id>_<core_id>/tune 57 57 $ ls 58 58 qos_tx_cpl qos_tx_np qos_tx_p 59 59 tx_path_rx_req_alloc_buf_level
+1 -1
MAINTAINERS
··· 9816 9816 M: Jonathan Cameron <jonathan.cameron@huawei.com> 9817 9817 L: linux-kernel@vger.kernel.org 9818 9818 S: Maintained 9819 - F: Documentation/ABI/testing/sysfs-devices-hisi_ptt 9819 + F: Documentation/ABI/testing/sysfs-bus-event_source-devices-hisi_ptt 9820 9820 F: Documentation/trace/hisi-ptt.rst 9821 9821 F: drivers/hwtracing/ptt/ 9822 9822 F: tools/perf/arch/arm64/util/hisi-ptt.c
-8
drivers/acpi/arm64/amba.c
··· 22 22 static const struct acpi_device_id amba_id_list[] = { 23 23 {"ARMH0061", 0}, /* PL061 GPIO Device */ 24 24 {"ARMH0330", 0}, /* ARM DMA Controller DMA-330 */ 25 - {"ARMHC501", 0}, /* ARM CoreSight ETR */ 26 - {"ARMHC502", 0}, /* ARM CoreSight STM */ 27 - {"ARMHC503", 0}, /* ARM CoreSight Debug */ 28 - {"ARMHC979", 0}, /* ARM CoreSight TPIU */ 29 - {"ARMHC97C", 0}, /* ARM CoreSight SoC-400 TMC, SoC-600 ETF/ETB */ 30 - {"ARMHC98D", 0}, /* ARM CoreSight Dynamic Replicator */ 31 - {"ARMHC9CA", 0}, /* ARM CoreSight CATU */ 32 - {"ARMHC9FF", 0}, /* ARM CoreSight Dynamic Funnel */ 33 25 {"", 0}, 34 26 }; 35 27
+118 -19
drivers/hwtracing/coresight/coresight-catu.c
··· 7 7 * Author: Suzuki K Poulose <suzuki.poulose@arm.com> 8 8 */ 9 9 10 + #include <linux/acpi.h> 10 11 #include <linux/amba/bus.h> 11 12 #include <linux/device.h> 12 13 #include <linux/dma-mapping.h> 13 14 #include <linux/io.h> 14 15 #include <linux/kernel.h> 16 + #include <linux/platform_device.h> 15 17 #include <linux/slab.h> 16 18 17 19 #include "coresight-catu.h" ··· 504 502 .helper_ops = &catu_helper_ops, 505 503 }; 506 504 507 - static int catu_probe(struct amba_device *adev, const struct amba_id *id) 505 + static int __catu_probe(struct device *dev, struct resource *res) 508 506 { 509 507 int ret = 0; 510 508 u32 dma_mask; 511 - struct catu_drvdata *drvdata; 509 + struct catu_drvdata *drvdata = dev_get_drvdata(dev); 512 510 struct coresight_desc catu_desc; 513 511 struct coresight_platform_data *pdata = NULL; 514 - struct device *dev = &adev->dev; 515 512 void __iomem *base; 516 513 517 514 catu_desc.name = coresight_alloc_device_name(&catu_devs, dev); 518 515 if (!catu_desc.name) 519 516 return -ENOMEM; 520 517 521 - drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); 522 - if (!drvdata) { 523 - ret = -ENOMEM; 524 - goto out; 525 - } 526 - 527 - dev_set_drvdata(dev, drvdata); 528 - base = devm_ioremap_resource(dev, &adev->res); 518 + base = devm_ioremap_resource(dev, res); 529 519 if (IS_ERR(base)) { 530 520 ret = PTR_ERR(base); 531 521 goto out; ··· 561 567 drvdata->csdev = coresight_register(&catu_desc); 562 568 if (IS_ERR(drvdata->csdev)) 563 569 ret = PTR_ERR(drvdata->csdev); 564 - else 565 - pm_runtime_put(&adev->dev); 566 570 out: 567 571 return ret; 568 572 } 569 573 570 - static void catu_remove(struct amba_device *adev) 574 + static int catu_probe(struct amba_device *adev, const struct amba_id *id) 571 575 { 572 - struct catu_drvdata *drvdata = dev_get_drvdata(&adev->dev); 576 + struct catu_drvdata *drvdata; 577 + int ret; 578 + 579 + drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL); 580 + if (!drvdata) 581 + return -ENOMEM; 582 + 583 + amba_set_drvdata(adev, drvdata); 584 + ret = __catu_probe(&adev->dev, &adev->res); 585 + if (!ret) 586 + pm_runtime_put(&adev->dev); 587 + 588 + return ret; 589 + } 590 + 591 + static void __catu_remove(struct device *dev) 592 + { 593 + struct catu_drvdata *drvdata = dev_get_drvdata(dev); 573 594 574 595 coresight_unregister(drvdata->csdev); 596 + } 597 + 598 + static void catu_remove(struct amba_device *adev) 599 + { 600 + __catu_remove(&adev->dev); 575 601 } 576 602 577 603 static struct amba_id catu_ids[] = { ··· 612 598 .id_table = catu_ids, 613 599 }; 614 600 601 + static int catu_platform_probe(struct platform_device *pdev) 602 + { 603 + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 604 + struct catu_drvdata *drvdata; 605 + int ret = 0; 606 + 607 + drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); 608 + if (!drvdata) 609 + return -ENOMEM; 610 + 611 + drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev); 612 + if (IS_ERR(drvdata->pclk)) 613 + return -ENODEV; 614 + 615 + pm_runtime_get_noresume(&pdev->dev); 616 + pm_runtime_set_active(&pdev->dev); 617 + pm_runtime_enable(&pdev->dev); 618 + 619 + dev_set_drvdata(&pdev->dev, drvdata); 620 + ret = __catu_probe(&pdev->dev, res); 621 + pm_runtime_put(&pdev->dev); 622 + if (ret) { 623 + pm_runtime_disable(&pdev->dev); 624 + if (!IS_ERR_OR_NULL(drvdata->pclk)) 625 + clk_put(drvdata->pclk); 626 + } 627 + 628 + return ret; 629 + } 630 + 631 + static void catu_platform_remove(struct platform_device *pdev) 632 + { 633 + struct catu_drvdata *drvdata = dev_get_drvdata(&pdev->dev); 634 + 635 + if (WARN_ON(!drvdata)) 636 + return; 637 + 638 + __catu_remove(&pdev->dev); 639 + pm_runtime_disable(&pdev->dev); 640 + if (!IS_ERR_OR_NULL(drvdata->pclk)) 641 + clk_put(drvdata->pclk); 642 + } 643 + 644 + #ifdef CONFIG_PM 645 + static int catu_runtime_suspend(struct device *dev) 646 + { 647 + struct catu_drvdata *drvdata = dev_get_drvdata(dev); 648 + 649 + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) 650 + clk_disable_unprepare(drvdata->pclk); 651 + return 0; 652 + } 653 + 654 + static int catu_runtime_resume(struct device *dev) 655 + { 656 + struct catu_drvdata *drvdata = dev_get_drvdata(dev); 657 + 658 + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) 659 + clk_prepare_enable(drvdata->pclk); 660 + return 0; 661 + } 662 + #endif 663 + 664 + static const struct dev_pm_ops catu_dev_pm_ops = { 665 + SET_RUNTIME_PM_OPS(catu_runtime_suspend, catu_runtime_resume, NULL) 666 + }; 667 + 668 + #ifdef CONFIG_ACPI 669 + static const struct acpi_device_id catu_acpi_ids[] = { 670 + {"ARMHC9CA", 0, 0, 0}, /* ARM CoreSight CATU */ 671 + {}, 672 + }; 673 + 674 + MODULE_DEVICE_TABLE(acpi, catu_acpi_ids); 675 + #endif 676 + 677 + static struct platform_driver catu_platform_driver = { 678 + .probe = catu_platform_probe, 679 + .remove_new = catu_platform_remove, 680 + .driver = { 681 + .name = "coresight-catu-platform", 682 + .acpi_match_table = ACPI_PTR(catu_acpi_ids), 683 + .suppress_bind_attrs = true, 684 + .pm = &catu_dev_pm_ops, 685 + }, 686 + }; 687 + 615 688 static int __init catu_init(void) 616 689 { 617 690 int ret; 618 691 619 - ret = amba_driver_register(&catu_driver); 620 - if (ret) 621 - pr_info("Error registering catu driver\n"); 692 + ret = coresight_init_driver("catu", &catu_driver, &catu_platform_driver); 622 693 tmc_etr_set_catu_ops(&etr_catu_buf_ops); 623 694 return ret; 624 695 } ··· 711 612 static void __exit catu_exit(void) 712 613 { 713 614 tmc_etr_remove_catu_ops(); 714 - amba_driver_unregister(&catu_driver); 615 + coresight_remove_driver(&catu_driver, &catu_platform_driver); 715 616 } 716 617 717 618 module_init(catu_init);
+1
drivers/hwtracing/coresight/coresight-catu.h
··· 61 61 #define CATU_IRQEN_OFF 0x0 62 62 63 63 struct catu_drvdata { 64 + struct clk *pclk; 64 65 void __iomem *base; 65 66 struct coresight_device *csdev; 66 67 int irq;
+29
drivers/hwtracing/coresight/coresight-core.c
··· 1398 1398 module_init(coresight_init); 1399 1399 module_exit(coresight_exit); 1400 1400 1401 + int coresight_init_driver(const char *drv, struct amba_driver *amba_drv, 1402 + struct platform_driver *pdev_drv) 1403 + { 1404 + int ret; 1405 + 1406 + ret = amba_driver_register(amba_drv); 1407 + if (ret) { 1408 + pr_err("%s: error registering AMBA driver\n", drv); 1409 + return ret; 1410 + } 1411 + 1412 + ret = platform_driver_register(pdev_drv); 1413 + if (!ret) 1414 + return 0; 1415 + 1416 + pr_err("%s: error registering platform driver\n", drv); 1417 + amba_driver_unregister(amba_drv); 1418 + return ret; 1419 + } 1420 + EXPORT_SYMBOL_GPL(coresight_init_driver); 1421 + 1422 + void coresight_remove_driver(struct amba_driver *amba_drv, 1423 + struct platform_driver *pdev_drv) 1424 + { 1425 + amba_driver_unregister(amba_drv); 1426 + platform_driver_unregister(pdev_drv); 1427 + } 1428 + EXPORT_SYMBOL_GPL(coresight_remove_driver); 1429 + 1401 1430 MODULE_LICENSE("GPL v2"); 1402 1431 MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>"); 1403 1432 MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
+121 -16
drivers/hwtracing/coresight/coresight-cpu-debug.c
··· 4 4 * 5 5 * Author: Leo Yan <leo.yan@linaro.org> 6 6 */ 7 + #include <linux/acpi.h> 7 8 #include <linux/amba/bus.h> 8 9 #include <linux/coresight.h> 9 10 #include <linux/cpu.h> ··· 19 18 #include <linux/module.h> 20 19 #include <linux/moduleparam.h> 21 20 #include <linux/panic_notifier.h> 21 + #include <linux/platform_device.h> 22 22 #include <linux/pm_qos.h> 23 23 #include <linux/slab.h> 24 24 #include <linux/smp.h> ··· 86 84 #define DEBUG_WAIT_TIMEOUT 32000 87 85 88 86 struct debug_drvdata { 87 + struct clk *pclk; 89 88 void __iomem *base; 90 89 struct device *dev; 91 90 int cpu; ··· 560 557 debugfs_remove_recursive(debug_debugfs_dir); 561 558 } 562 559 563 - static int debug_probe(struct amba_device *adev, const struct amba_id *id) 560 + static int __debug_probe(struct device *dev, struct resource *res) 564 561 { 562 + struct debug_drvdata *drvdata = dev_get_drvdata(dev); 565 563 void __iomem *base; 566 - struct device *dev = &adev->dev; 567 - struct debug_drvdata *drvdata; 568 - struct resource *res = &adev->res; 569 564 int ret; 570 - 571 - drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); 572 - if (!drvdata) 573 - return -ENOMEM; 574 565 575 566 drvdata->cpu = coresight_get_cpu(dev); 576 567 if (drvdata->cpu < 0) ··· 576 579 return -EBUSY; 577 580 } 578 581 579 - drvdata->dev = &adev->dev; 580 - amba_set_drvdata(adev, drvdata); 581 - 582 - /* Validity for the resource is already checked by the AMBA core */ 582 + drvdata->dev = dev; 583 583 base = devm_ioremap_resource(dev, res); 584 584 if (IS_ERR(base)) 585 585 return PTR_ERR(base); ··· 623 629 return ret; 624 630 } 625 631 626 - static void debug_remove(struct amba_device *adev) 632 + static int debug_probe(struct amba_device *adev, const struct amba_id *id) 627 633 { 628 - struct device *dev = &adev->dev; 629 - struct debug_drvdata *drvdata = amba_get_drvdata(adev); 634 + struct debug_drvdata *drvdata; 635 + 636 + drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL); 637 + if (!drvdata) 638 + return -ENOMEM; 639 + 640 + amba_set_drvdata(adev, drvdata); 641 + return __debug_probe(&adev->dev, &adev->res); 642 + } 643 + 644 + static void __debug_remove(struct device *dev) 645 + { 646 + struct debug_drvdata *drvdata = dev_get_drvdata(dev); 630 647 631 648 per_cpu(debug_drvdata, drvdata->cpu) = NULL; 632 649 ··· 649 644 650 645 if (!--debug_count) 651 646 debug_func_exit(); 647 + } 648 + 649 + static void debug_remove(struct amba_device *adev) 650 + { 651 + __debug_remove(&adev->dev); 652 652 } 653 653 654 654 static const struct amba_cs_uci_id uci_id_debug[] = { ··· 687 677 .id_table = debug_ids, 688 678 }; 689 679 690 - module_amba_driver(debug_driver); 680 + static int debug_platform_probe(struct platform_device *pdev) 681 + { 682 + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 683 + struct debug_drvdata *drvdata; 684 + int ret = 0; 685 + 686 + drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); 687 + if (!drvdata) 688 + return -ENOMEM; 689 + 690 + drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev); 691 + if (IS_ERR(drvdata->pclk)) 692 + return -ENODEV; 693 + 694 + dev_set_drvdata(&pdev->dev, drvdata); 695 + pm_runtime_get_noresume(&pdev->dev); 696 + pm_runtime_set_active(&pdev->dev); 697 + pm_runtime_enable(&pdev->dev); 698 + 699 + ret = __debug_probe(&pdev->dev, res); 700 + if (ret) { 701 + pm_runtime_put_noidle(&pdev->dev); 702 + pm_runtime_disable(&pdev->dev); 703 + if (!IS_ERR_OR_NULL(drvdata->pclk)) 704 + clk_put(drvdata->pclk); 705 + } 706 + return ret; 707 + } 708 + 709 + static void debug_platform_remove(struct platform_device *pdev) 710 + { 711 + struct debug_drvdata *drvdata = dev_get_drvdata(&pdev->dev); 712 + 713 + if (WARN_ON(!drvdata)) 714 + return; 715 + 716 + __debug_remove(&pdev->dev); 717 + pm_runtime_disable(&pdev->dev); 718 + if (!IS_ERR_OR_NULL(drvdata->pclk)) 719 + clk_put(drvdata->pclk); 720 + } 721 + 722 + #ifdef CONFIG_ACPI 723 + static const struct acpi_device_id debug_platform_ids[] = { 724 + {"ARMHC503", 0, 0, 0}, /* ARM CoreSight Debug */ 725 + {}, 726 + }; 727 + MODULE_DEVICE_TABLE(acpi, debug_platform_ids); 728 + #endif 729 + 730 + #ifdef CONFIG_PM 731 + static int debug_runtime_suspend(struct device *dev) 732 + { 733 + struct debug_drvdata *drvdata = dev_get_drvdata(dev); 734 + 735 + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) 736 + clk_disable_unprepare(drvdata->pclk); 737 + return 0; 738 + } 739 + 740 + static int debug_runtime_resume(struct device *dev) 741 + { 742 + struct debug_drvdata *drvdata = dev_get_drvdata(dev); 743 + 744 + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) 745 + clk_prepare_enable(drvdata->pclk); 746 + return 0; 747 + } 748 + #endif 749 + 750 + static const struct dev_pm_ops debug_dev_pm_ops = { 751 + SET_RUNTIME_PM_OPS(debug_runtime_suspend, debug_runtime_resume, NULL) 752 + }; 753 + 754 + static struct platform_driver debug_platform_driver = { 755 + .probe = debug_platform_probe, 756 + .remove_new = debug_platform_remove, 757 + .driver = { 758 + .name = "coresight-debug-platform", 759 + .acpi_match_table = ACPI_PTR(debug_platform_ids), 760 + .suppress_bind_attrs = true, 761 + .pm = &debug_dev_pm_ops, 762 + }, 763 + }; 764 + 765 + static int __init debug_init(void) 766 + { 767 + return coresight_init_driver("debug", &debug_driver, &debug_platform_driver); 768 + } 769 + 770 + static void __exit debug_exit(void) 771 + { 772 + coresight_remove_driver(&debug_driver, &debug_platform_driver); 773 + } 774 + module_init(debug_init); 775 + module_exit(debug_exit); 691 776 692 777 MODULE_AUTHOR("Leo Yan <leo.yan@linaro.org>"); 693 778 MODULE_DESCRIPTION("ARM Coresight CPU Debug Driver");
+17 -12
drivers/hwtracing/coresight/coresight-etm4x-core.c
··· 1240 1240 drvdata->nr_event = FIELD_GET(TRCIDR0_NUMEVENT_MASK, etmidr0); 1241 1241 /* QSUPP, bits[16:15] Q element support field */ 1242 1242 drvdata->q_support = FIELD_GET(TRCIDR0_QSUPP_MASK, etmidr0); 1243 + if (drvdata->q_support) 1244 + drvdata->q_filt = !!(etmidr0 & TRCIDR0_QFILT); 1243 1245 /* TSSIZE, bits[28:24] Global timestamp size field */ 1244 1246 drvdata->ts_size = FIELD_GET(TRCIDR0_TSSIZE_MASK, etmidr0); 1245 1247 ··· 1734 1732 state->trcccctlr = etm4x_read32(csa, TRCCCCTLR); 1735 1733 state->trcbbctlr = etm4x_read32(csa, TRCBBCTLR); 1736 1734 state->trctraceidr = etm4x_read32(csa, TRCTRACEIDR); 1737 - state->trcqctlr = etm4x_read32(csa, TRCQCTLR); 1735 + if (drvdata->q_filt) 1736 + state->trcqctlr = etm4x_read32(csa, TRCQCTLR); 1738 1737 1739 1738 state->trcvictlr = etm4x_read32(csa, TRCVICTLR); 1740 1739 state->trcviiectlr = etm4x_read32(csa, TRCVIIECTLR); 1741 1740 state->trcvissctlr = etm4x_read32(csa, TRCVISSCTLR); 1742 1741 if (drvdata->nr_pe_cmp) 1743 1742 state->trcvipcssctlr = etm4x_read32(csa, TRCVIPCSSCTLR); 1744 - state->trcvdctlr = etm4x_read32(csa, TRCVDCTLR); 1745 - state->trcvdsacctlr = etm4x_read32(csa, TRCVDSACCTLR); 1746 - state->trcvdarcctlr = etm4x_read32(csa, TRCVDARCCTLR); 1747 1743 1748 1744 for (i = 0; i < drvdata->nrseqstate - 1; i++) 1749 1745 state->trcseqevr[i] = etm4x_read32(csa, TRCSEQEVRn(i)); ··· 1758 1758 state->trccntvr[i] = etm4x_read32(csa, TRCCNTVRn(i)); 1759 1759 } 1760 1760 1761 - for (i = 0; i < drvdata->nr_resource * 2; i++) 1761 + /* Resource selector pair 0 is reserved */ 1762 + for (i = 2; i < drvdata->nr_resource * 2; i++) 1762 1763 state->trcrsctlr[i] = etm4x_read32(csa, TRCRSCTLRn(i)); 1763 1764 1764 1765 for (i = 0; i < drvdata->nr_ss_cmp; i++) { ··· 1844 1843 { 1845 1844 int i; 1846 1845 struct etmv4_save_state *state = drvdata->save_state; 1847 - struct csdev_access tmp_csa = CSDEV_ACCESS_IOMEM(drvdata->base); 1848 - struct csdev_access *csa = &tmp_csa; 1846 + struct csdev_access *csa = &drvdata->csdev->access; 1847 + 1848 + if (WARN_ON(!drvdata->csdev)) 1849 + return; 1849 1850 1850 1851 etm4_cs_unlock(drvdata, csa); 1851 1852 etm4x_relaxed_write32(csa, state->trcclaimset, TRCCLAIMSET); ··· 1866 1863 etm4x_relaxed_write32(csa, state->trcccctlr, TRCCCCTLR); 1867 1864 etm4x_relaxed_write32(csa, state->trcbbctlr, TRCBBCTLR); 1868 1865 etm4x_relaxed_write32(csa, state->trctraceidr, TRCTRACEIDR); 1869 - etm4x_relaxed_write32(csa, state->trcqctlr, TRCQCTLR); 1866 + if (drvdata->q_filt) 1867 + etm4x_relaxed_write32(csa, state->trcqctlr, TRCQCTLR); 1870 1868 1871 1869 etm4x_relaxed_write32(csa, state->trcvictlr, TRCVICTLR); 1872 1870 etm4x_relaxed_write32(csa, state->trcviiectlr, TRCVIIECTLR); 1873 1871 etm4x_relaxed_write32(csa, state->trcvissctlr, TRCVISSCTLR); 1874 1872 if (drvdata->nr_pe_cmp) 1875 1873 etm4x_relaxed_write32(csa, state->trcvipcssctlr, TRCVIPCSSCTLR); 1876 - etm4x_relaxed_write32(csa, state->trcvdctlr, TRCVDCTLR); 1877 - etm4x_relaxed_write32(csa, state->trcvdsacctlr, TRCVDSACCTLR); 1878 - etm4x_relaxed_write32(csa, state->trcvdarcctlr, TRCVDARCCTLR); 1879 1874 1880 1875 for (i = 0; i < drvdata->nrseqstate - 1; i++) 1881 1876 etm4x_relaxed_write32(csa, state->trcseqevr[i], TRCSEQEVRn(i)); ··· 1890 1889 etm4x_relaxed_write32(csa, state->trccntvr[i], TRCCNTVRn(i)); 1891 1890 } 1892 1891 1893 - for (i = 0; i < drvdata->nr_resource * 2; i++) 1892 + /* Resource selector pair 0 is reserved */ 1893 + for (i = 2; i < drvdata->nr_resource * 2; i++) 1894 1894 etm4x_relaxed_write32(csa, state->trcrsctlr[i], TRCRSCTLRn(i)); 1895 1895 1896 1896 for (i = 0; i < drvdata->nr_ss_cmp; i++) { ··· 2215 2213 ret = etm4_probe(&pdev->dev); 2216 2214 2217 2215 pm_runtime_put(&pdev->dev); 2216 + if (ret) 2217 + pm_runtime_disable(&pdev->dev); 2218 + 2218 2219 return ret; 2219 2220 } 2220 2221
+3 -28
drivers/hwtracing/coresight/coresight-etm4x.h
··· 43 43 #define TRCVIIECTLR 0x084 44 44 #define TRCVISSCTLR 0x088 45 45 #define TRCVIPCSSCTLR 0x08C 46 - #define TRCVDCTLR 0x0A0 47 - #define TRCVDSACCTLR 0x0A4 48 - #define TRCVDARCCTLR 0x0A8 49 46 /* Derived resources registers */ 50 47 #define TRCSEQEVRn(n) (0x100 + (n * 4)) /* n = 0-2 */ 51 48 #define TRCSEQRSTEVR 0x118 ··· 87 90 /* Address Comparator registers n = 0-15 */ 88 91 #define TRCACVRn(n) (0x400 + (n * 8)) 89 92 #define TRCACATRn(n) (0x480 + (n * 8)) 90 - /* Data Value Comparator Value registers, n = 0-7 */ 91 - #define TRCDVCVRn(n) (0x500 + (n * 16)) 92 - #define TRCDVCMRn(n) (0x580 + (n * 16)) 93 93 /* ContextID/Virtual ContextID comparators, n = 0-7 */ 94 94 #define TRCCIDCVRn(n) (0x600 + (n * 8)) 95 95 #define TRCVMIDCVRn(n) (0x640 + (n * 8)) ··· 135 141 #define TRCIDR0_TRCCCI BIT(7) 136 142 #define TRCIDR0_RETSTACK BIT(9) 137 143 #define TRCIDR0_NUMEVENT_MASK GENMASK(11, 10) 144 + #define TRCIDR0_QFILT BIT(14) 138 145 #define TRCIDR0_QSUPP_MASK GENMASK(16, 15) 139 146 #define TRCIDR0_TSSIZE_MASK GENMASK(28, 24) 140 147 ··· 267 272 /* List of registers accessible via System instructions */ 268 273 #define ETM4x_ONLY_SYSREG_LIST(op, val) \ 269 274 CASE_##op((val), TRCPROCSELR) \ 270 - CASE_##op((val), TRCVDCTLR) \ 271 - CASE_##op((val), TRCVDSACCTLR) \ 272 - CASE_##op((val), TRCVDARCCTLR) \ 273 275 CASE_##op((val), TRCOSLAR) 274 276 275 277 #define ETM_COMMON_SYSREG_LIST(op, val) \ ··· 414 422 CASE_##op((val), TRCACATRn(13)) \ 415 423 CASE_##op((val), TRCACATRn(14)) \ 416 424 CASE_##op((val), TRCACATRn(15)) \ 417 - CASE_##op((val), TRCDVCVRn(0)) \ 418 - CASE_##op((val), TRCDVCVRn(1)) \ 419 - CASE_##op((val), TRCDVCVRn(2)) \ 420 - CASE_##op((val), TRCDVCVRn(3)) \ 421 - CASE_##op((val), TRCDVCVRn(4)) \ 422 - CASE_##op((val), TRCDVCVRn(5)) \ 423 - CASE_##op((val), TRCDVCVRn(6)) \ 424 - CASE_##op((val), TRCDVCVRn(7)) \ 425 - CASE_##op((val), TRCDVCMRn(0)) \ 426 - CASE_##op((val), TRCDVCMRn(1)) \ 427 - CASE_##op((val), TRCDVCMRn(2)) \ 428 - CASE_##op((val), TRCDVCMRn(3)) \ 429 - CASE_##op((val), TRCDVCMRn(4)) \ 430 - CASE_##op((val), TRCDVCMRn(5)) \ 431 - CASE_##op((val), TRCDVCMRn(6)) \ 432 - CASE_##op((val), TRCDVCMRn(7)) \ 433 425 CASE_##op((val), TRCCIDCVRn(0)) \ 434 426 CASE_##op((val), TRCCIDCVRn(1)) \ 435 427 CASE_##op((val), TRCCIDCVRn(2)) \ ··· 883 907 u32 trcviiectlr; 884 908 u32 trcvissctlr; 885 909 u32 trcvipcssctlr; 886 - u32 trcvdctlr; 887 - u32 trcvdsacctlr; 888 - u32 trcvdarcctlr; 889 910 890 911 u32 trcseqevr[ETM_MAX_SEQ_STATES]; 891 912 u32 trcseqrstevr; ··· 955 982 * @os_unlock: True if access to management registers is allowed. 956 983 * @instrp0: Tracing of load and store instructions 957 984 * as P0 elements is supported. 985 + * @q_filt: Q element filtering support, if Q elements are supported. 958 986 * @trcbb: Indicates if the trace unit supports branch broadcast tracing. 959 987 * @trccond: If the trace unit supports conditional 960 988 * instruction tracing. ··· 1018 1044 bool boot_enable; 1019 1045 bool os_unlock; 1020 1046 bool instrp0; 1047 + bool q_filt; 1021 1048 bool trcbb; 1022 1049 bool trccond; 1023 1050 bool retstack;
+48 -39
drivers/hwtracing/coresight/coresight-funnel.c
··· 36 36 * struct funnel_drvdata - specifics associated to a funnel component 37 37 * @base: memory mapped base address for this component. 38 38 * @atclk: optional clock for the core parts of the funnel. 39 + * @pclk: APB clock if present, otherwise NULL 39 40 * @csdev: component vitals needed by the framework. 40 41 * @priority: port selection order. 41 42 * @spinlock: serialize enable/disable operations. ··· 44 43 struct funnel_drvdata { 45 44 void __iomem *base; 46 45 struct clk *atclk; 46 + struct clk *pclk; 47 47 struct coresight_device *csdev; 48 48 unsigned long priority; 49 49 spinlock_t spinlock; ··· 238 236 return ret; 239 237 } 240 238 239 + drvdata->pclk = coresight_get_enable_apb_pclk(dev); 240 + if (IS_ERR(drvdata->pclk)) 241 + return -ENODEV; 242 + 241 243 /* 242 244 * Map the device base for dynamic-funnel, which has been 243 245 * validated by AMBA core. ··· 278 272 goto out_disable_clk; 279 273 } 280 274 281 - pm_runtime_put(dev); 282 275 ret = 0; 283 276 284 277 out_disable_clk: 285 278 if (ret && !IS_ERR_OR_NULL(drvdata->atclk)) 286 279 clk_disable_unprepare(drvdata->atclk); 280 + if (ret && !IS_ERR_OR_NULL(drvdata->pclk)) 281 + clk_disable_unprepare(drvdata->pclk); 287 282 return ret; 288 283 } 289 284 ··· 305 298 if (drvdata && !IS_ERR(drvdata->atclk)) 306 299 clk_disable_unprepare(drvdata->atclk); 307 300 301 + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) 302 + clk_disable_unprepare(drvdata->pclk); 303 + 308 304 return 0; 309 305 } 310 306 ··· 318 308 if (drvdata && !IS_ERR(drvdata->atclk)) 319 309 clk_prepare_enable(drvdata->atclk); 320 310 311 + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) 312 + clk_prepare_enable(drvdata->pclk); 321 313 return 0; 322 314 } 323 315 #endif ··· 328 316 SET_RUNTIME_PM_OPS(funnel_runtime_suspend, funnel_runtime_resume, NULL) 329 317 }; 330 318 331 - static int static_funnel_probe(struct platform_device *pdev) 319 + static int funnel_platform_probe(struct platform_device *pdev) 332 320 { 321 + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 333 322 int ret; 334 323 335 324 pm_runtime_get_noresume(&pdev->dev); 336 325 pm_runtime_set_active(&pdev->dev); 337 326 pm_runtime_enable(&pdev->dev); 338 327 339 - /* Static funnel do not have programming base */ 340 - ret = funnel_probe(&pdev->dev, NULL); 341 - 342 - if (ret) { 343 - pm_runtime_put_noidle(&pdev->dev); 328 + ret = funnel_probe(&pdev->dev, res); 329 + pm_runtime_put(&pdev->dev); 330 + if (ret) 344 331 pm_runtime_disable(&pdev->dev); 345 - } 346 332 347 333 return ret; 348 334 } 349 335 350 - static void static_funnel_remove(struct platform_device *pdev) 336 + static void funnel_platform_remove(struct platform_device *pdev) 351 337 { 338 + struct funnel_drvdata *drvdata = dev_get_drvdata(&pdev->dev); 339 + 340 + if (WARN_ON(!drvdata)) 341 + return; 342 + 352 343 funnel_remove(&pdev->dev); 353 344 pm_runtime_disable(&pdev->dev); 345 + if (!IS_ERR_OR_NULL(drvdata->pclk)) 346 + clk_put(drvdata->pclk); 354 347 } 355 348 356 - static const struct of_device_id static_funnel_match[] = { 349 + static const struct of_device_id funnel_match[] = { 357 350 {.compatible = "arm,coresight-static-funnel"}, 358 351 {} 359 352 }; 360 353 361 - MODULE_DEVICE_TABLE(of, static_funnel_match); 354 + MODULE_DEVICE_TABLE(of, funnel_match); 362 355 363 356 #ifdef CONFIG_ACPI 364 - static const struct acpi_device_id static_funnel_ids[] = { 365 - {"ARMHC9FE", 0, 0, 0}, 357 + static const struct acpi_device_id funnel_acpi_ids[] = { 358 + {"ARMHC9FE", 0, 0, 0}, /* ARM Coresight Static Funnel */ 359 + {"ARMHC9FF", 0, 0, 0}, /* ARM CoreSight Dynamic Funnel */ 366 360 {}, 367 361 }; 368 362 369 - MODULE_DEVICE_TABLE(acpi, static_funnel_ids); 363 + MODULE_DEVICE_TABLE(acpi, funnel_acpi_ids); 370 364 #endif 371 365 372 - static struct platform_driver static_funnel_driver = { 373 - .probe = static_funnel_probe, 374 - .remove_new = static_funnel_remove, 375 - .driver = { 376 - .name = "coresight-static-funnel", 366 + static struct platform_driver funnel_driver = { 367 + .probe = funnel_platform_probe, 368 + .remove_new = funnel_platform_remove, 369 + .driver = { 370 + .name = "coresight-funnel", 377 371 /* THIS_MODULE is taken care of by platform_driver_register() */ 378 - .of_match_table = static_funnel_match, 379 - .acpi_match_table = ACPI_PTR(static_funnel_ids), 372 + .of_match_table = funnel_match, 373 + .acpi_match_table = ACPI_PTR(funnel_acpi_ids), 380 374 .pm = &funnel_dev_pm_ops, 381 375 .suppress_bind_attrs = true, 382 376 }, ··· 391 373 static int dynamic_funnel_probe(struct amba_device *adev, 392 374 const struct amba_id *id) 393 375 { 394 - return funnel_probe(&adev->dev, &adev->res); 376 + int ret; 377 + 378 + ret = funnel_probe(&adev->dev, &adev->res); 379 + if (!ret) 380 + pm_runtime_put(&adev->dev); 381 + 382 + return ret; 395 383 } 396 384 397 385 static void dynamic_funnel_remove(struct amba_device *adev) ··· 434 410 435 411 static int __init funnel_init(void) 436 412 { 437 - int ret; 438 - 439 - ret = platform_driver_register(&static_funnel_driver); 440 - if (ret) { 441 - pr_info("Error registering platform driver\n"); 442 - return ret; 443 - } 444 - 445 - ret = amba_driver_register(&dynamic_funnel_driver); 446 - if (ret) { 447 - pr_info("Error registering amba driver\n"); 448 - platform_driver_unregister(&static_funnel_driver); 449 - } 450 - 451 - return ret; 413 + return coresight_init_driver("funnel", &dynamic_funnel_driver, &funnel_driver); 452 414 } 453 415 454 416 static void __exit funnel_exit(void) 455 417 { 456 - platform_driver_unregister(&static_funnel_driver); 457 - amba_driver_unregister(&dynamic_funnel_driver); 418 + coresight_remove_driver(&dynamic_funnel_driver, &funnel_driver); 458 419 } 459 420 460 421 module_init(funnel_init);
+10
drivers/hwtracing/coresight/coresight-priv.h
··· 222 222 return uci_id->data; 223 223 } 224 224 225 + static inline void *coresight_get_uci_data_from_amba(const struct amba_id *table, u32 pid) 226 + { 227 + while (table->mask) { 228 + if ((pid & table->mask) == table->id) 229 + return coresight_get_uci_data(table); 230 + table++; 231 + }; 232 + return NULL; 233 + } 234 + 225 235 void coresight_release_platform_data(struct coresight_device *csdev, 226 236 struct device *dev, 227 237 struct coresight_platform_data *pdata);
+45 -37
drivers/hwtracing/coresight/coresight-replicator.c
··· 31 31 * @base: memory mapped base address for this component. Also indicates 32 32 * whether this one is programmable or not. 33 33 * @atclk: optional clock for the core parts of the replicator. 34 + * @pclk: APB clock if present, otherwise NULL 34 35 * @csdev: component vitals needed by the framework 35 36 * @spinlock: serialize enable/disable operations. 36 37 * @check_idfilter_val: check if the context is lost upon clock removal. ··· 39 38 struct replicator_drvdata { 40 39 void __iomem *base; 41 40 struct clk *atclk; 41 + struct clk *pclk; 42 42 struct coresight_device *csdev; 43 43 spinlock_t spinlock; 44 44 bool check_idfilter_val; ··· 245 243 return ret; 246 244 } 247 245 246 + drvdata->pclk = coresight_get_enable_apb_pclk(dev); 247 + if (IS_ERR(drvdata->pclk)) 248 + return -ENODEV; 249 + 248 250 /* 249 251 * Map the device base for dynamic-replicator, which has been 250 252 * validated by AMBA core ··· 291 285 } 292 286 293 287 replicator_reset(drvdata); 294 - pm_runtime_put(dev); 295 288 296 289 out_disable_clk: 297 290 if (ret && !IS_ERR_OR_NULL(drvdata->atclk)) 298 291 clk_disable_unprepare(drvdata->atclk); 292 + if (ret && !IS_ERR_OR_NULL(drvdata->pclk)) 293 + clk_disable_unprepare(drvdata->pclk); 299 294 return ret; 300 295 } 301 296 ··· 308 301 return 0; 309 302 } 310 303 311 - static int static_replicator_probe(struct platform_device *pdev) 304 + static int replicator_platform_probe(struct platform_device *pdev) 312 305 { 306 + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 313 307 int ret; 314 308 315 309 pm_runtime_get_noresume(&pdev->dev); 316 310 pm_runtime_set_active(&pdev->dev); 317 311 pm_runtime_enable(&pdev->dev); 318 312 319 - /* Static replicators do not have programming base */ 320 - ret = replicator_probe(&pdev->dev, NULL); 321 - 322 - if (ret) { 323 - pm_runtime_put_noidle(&pdev->dev); 313 + ret = replicator_probe(&pdev->dev, res); 314 + pm_runtime_put(&pdev->dev); 315 + if (ret) 324 316 pm_runtime_disable(&pdev->dev); 325 - } 326 317 327 318 return ret; 328 319 } 329 320 330 - static void static_replicator_remove(struct platform_device *pdev) 321 + static void replicator_platform_remove(struct platform_device *pdev) 331 322 { 323 + struct replicator_drvdata *drvdata = dev_get_drvdata(&pdev->dev); 324 + 325 + if (WARN_ON(!drvdata)) 326 + return; 327 + 332 328 replicator_remove(&pdev->dev); 333 329 pm_runtime_disable(&pdev->dev); 330 + if (!IS_ERR_OR_NULL(drvdata->pclk)) 331 + clk_put(drvdata->pclk); 334 332 } 335 333 336 334 #ifdef CONFIG_PM ··· 346 334 if (drvdata && !IS_ERR(drvdata->atclk)) 347 335 clk_disable_unprepare(drvdata->atclk); 348 336 337 + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) 338 + clk_disable_unprepare(drvdata->pclk); 349 339 return 0; 350 340 } 351 341 ··· 358 344 if (drvdata && !IS_ERR(drvdata->atclk)) 359 345 clk_prepare_enable(drvdata->atclk); 360 346 347 + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) 348 + clk_prepare_enable(drvdata->pclk); 361 349 return 0; 362 350 } 363 351 #endif ··· 369 353 replicator_runtime_resume, NULL) 370 354 }; 371 355 372 - static const struct of_device_id static_replicator_match[] = { 356 + static const struct of_device_id replicator_match[] = { 373 357 {.compatible = "arm,coresight-replicator"}, 374 358 {.compatible = "arm,coresight-static-replicator"}, 375 359 {} 376 360 }; 377 361 378 - MODULE_DEVICE_TABLE(of, static_replicator_match); 362 + MODULE_DEVICE_TABLE(of, replicator_match); 379 363 380 364 #ifdef CONFIG_ACPI 381 - static const struct acpi_device_id static_replicator_acpi_ids[] = { 365 + static const struct acpi_device_id replicator_acpi_ids[] = { 382 366 {"ARMHC985", 0, 0, 0}, /* ARM CoreSight Static Replicator */ 367 + {"ARMHC98D", 0, 0, 0}, /* ARM CoreSight Dynamic Replicator */ 383 368 {} 384 369 }; 385 370 386 - MODULE_DEVICE_TABLE(acpi, static_replicator_acpi_ids); 371 + MODULE_DEVICE_TABLE(acpi, replicator_acpi_ids); 387 372 #endif 388 373 389 - static struct platform_driver static_replicator_driver = { 390 - .probe = static_replicator_probe, 391 - .remove_new = static_replicator_remove, 374 + static struct platform_driver replicator_driver = { 375 + .probe = replicator_platform_probe, 376 + .remove_new = replicator_platform_remove, 392 377 .driver = { 393 - .name = "coresight-static-replicator", 378 + .name = "coresight-replicator", 394 379 /* THIS_MODULE is taken care of by platform_driver_register() */ 395 - .of_match_table = of_match_ptr(static_replicator_match), 396 - .acpi_match_table = ACPI_PTR(static_replicator_acpi_ids), 380 + .of_match_table = of_match_ptr(replicator_match), 381 + .acpi_match_table = ACPI_PTR(replicator_acpi_ids), 397 382 .pm = &replicator_dev_pm_ops, 398 383 .suppress_bind_attrs = true, 399 384 }, ··· 403 386 static int dynamic_replicator_probe(struct amba_device *adev, 404 387 const struct amba_id *id) 405 388 { 406 - return replicator_probe(&adev->dev, &adev->res); 389 + int ret; 390 + 391 + ret = replicator_probe(&adev->dev, &adev->res); 392 + if (!ret) 393 + pm_runtime_put(&adev->dev); 394 + 395 + return ret; 407 396 } 408 397 409 398 static void dynamic_replicator_remove(struct amba_device *adev) ··· 439 416 440 417 static int __init replicator_init(void) 441 418 { 442 - int ret; 443 - 444 - ret = platform_driver_register(&static_replicator_driver); 445 - if (ret) { 446 - pr_info("Error registering platform driver\n"); 447 - return ret; 448 - } 449 - 450 - ret = amba_driver_register(&dynamic_replicator_driver); 451 - if (ret) { 452 - pr_info("Error registering amba driver\n"); 453 - platform_driver_unregister(&static_replicator_driver); 454 - } 455 - 456 - return ret; 419 + return coresight_init_driver("replicator", &dynamic_replicator_driver, &replicator_driver); 457 420 } 458 421 459 422 static void __exit replicator_exit(void) 460 423 { 461 - platform_driver_unregister(&static_replicator_driver); 462 - amba_driver_unregister(&dynamic_replicator_driver); 424 + coresight_remove_driver(&dynamic_replicator_driver, &replicator_driver); 463 425 } 464 426 465 427 module_init(replicator_init);
+103 -11
drivers/hwtracing/coresight/coresight-stm.c
··· 29 29 #include <linux/perf_event.h> 30 30 #include <linux/pm_runtime.h> 31 31 #include <linux/stm.h> 32 + #include <linux/platform_device.h> 32 33 33 34 #include "coresight-priv.h" 34 35 #include "coresight-trace-id.h" ··· 116 115 * struct stm_drvdata - specifics associated to an STM component 117 116 * @base: memory mapped base address for this component. 118 117 * @atclk: optional clock for the core parts of the STM. 118 + * @pclk: APB clock if present, otherwise NULL 119 119 * @csdev: component vitals needed by the framework. 120 120 * @spinlock: only one at a time pls. 121 121 * @chs: the channels accociated to this STM. ··· 133 131 struct stm_drvdata { 134 132 void __iomem *base; 135 133 struct clk *atclk; 134 + struct clk *pclk; 136 135 struct coresight_device *csdev; 137 136 spinlock_t spinlock; 138 137 struct channel_space chs; ··· 803 800 drvdata->stm.set_options = stm_generic_set_options; 804 801 } 805 802 806 - static int stm_probe(struct amba_device *adev, const struct amba_id *id) 803 + static const struct amba_id stm_ids[]; 804 + 805 + static char *stm_csdev_name(struct coresight_device *csdev) 806 + { 807 + u32 stm_pid = coresight_get_pid(&csdev->access); 808 + void *uci_data = coresight_get_uci_data_from_amba(stm_ids, stm_pid); 809 + 810 + return uci_data ? (char *)uci_data : "STM"; 811 + } 812 + 813 + static int __stm_probe(struct device *dev, struct resource *res) 807 814 { 808 815 int ret, trace_id; 809 816 void __iomem *base; 810 - struct device *dev = &adev->dev; 811 817 struct coresight_platform_data *pdata = NULL; 812 818 struct stm_drvdata *drvdata; 813 - struct resource *res = &adev->res; 814 819 struct resource ch_res; 815 820 struct coresight_desc desc = { 0 }; 816 821 ··· 830 819 if (!drvdata) 831 820 return -ENOMEM; 832 821 833 - drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */ 822 + drvdata->atclk = devm_clk_get(dev, "atclk"); /* optional */ 834 823 if (!IS_ERR(drvdata->atclk)) { 835 824 ret = clk_prepare_enable(drvdata->atclk); 836 825 if (ret) 837 826 return ret; 838 827 } 828 + 829 + drvdata->pclk = coresight_get_enable_apb_pclk(dev); 830 + if (IS_ERR(drvdata->pclk)) 831 + return -ENODEV; 839 832 dev_set_drvdata(dev, drvdata); 840 833 841 834 base = devm_ioremap_resource(dev, res); ··· 887 872 ret = PTR_ERR(pdata); 888 873 goto stm_unregister; 889 874 } 890 - adev->dev.platform_data = pdata; 875 + dev->platform_data = pdata; 891 876 892 877 desc.type = CORESIGHT_DEV_TYPE_SOURCE; 893 878 desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE; ··· 908 893 } 909 894 drvdata->traceid = (u8)trace_id; 910 895 911 - pm_runtime_put(&adev->dev); 912 - 913 896 dev_info(&drvdata->csdev->dev, "%s initialized\n", 914 - (char *)coresight_get_uci_data(id)); 897 + stm_csdev_name(drvdata->csdev)); 915 898 return 0; 916 899 917 900 cs_unregister: ··· 920 907 return ret; 921 908 } 922 909 923 - static void stm_remove(struct amba_device *adev) 910 + static int stm_probe(struct amba_device *adev, const struct amba_id *id) 924 911 { 925 - struct stm_drvdata *drvdata = dev_get_drvdata(&adev->dev); 912 + int ret; 913 + 914 + ret = __stm_probe(&adev->dev, &adev->res); 915 + if (!ret) 916 + pm_runtime_put(&adev->dev); 917 + 918 + return ret; 919 + } 920 + 921 + static void __stm_remove(struct device *dev) 922 + { 923 + struct stm_drvdata *drvdata = dev_get_drvdata(dev); 926 924 927 925 coresight_trace_id_put_system_id(drvdata->traceid); 928 926 coresight_unregister(drvdata->csdev); 929 927 930 928 stm_unregister_device(&drvdata->stm); 929 + } 930 + 931 + static void stm_remove(struct amba_device *adev) 932 + { 933 + __stm_remove(&adev->dev); 931 934 } 932 935 933 936 #ifdef CONFIG_PM ··· 954 925 if (drvdata && !IS_ERR(drvdata->atclk)) 955 926 clk_disable_unprepare(drvdata->atclk); 956 927 928 + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) 929 + clk_disable_unprepare(drvdata->pclk); 957 930 return 0; 958 931 } 959 932 ··· 966 935 if (drvdata && !IS_ERR(drvdata->atclk)) 967 936 clk_prepare_enable(drvdata->atclk); 968 937 938 + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) 939 + clk_prepare_enable(drvdata->pclk); 969 940 return 0; 970 941 } 971 942 #endif ··· 996 963 .id_table = stm_ids, 997 964 }; 998 965 999 - module_amba_driver(stm_driver); 966 + static int stm_platform_probe(struct platform_device *pdev) 967 + { 968 + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 969 + int ret = 0; 970 + 971 + pm_runtime_get_noresume(&pdev->dev); 972 + pm_runtime_set_active(&pdev->dev); 973 + pm_runtime_enable(&pdev->dev); 974 + 975 + ret = __stm_probe(&pdev->dev, res); 976 + pm_runtime_put(&pdev->dev); 977 + if (ret) 978 + pm_runtime_disable(&pdev->dev); 979 + 980 + return ret; 981 + } 982 + 983 + static void stm_platform_remove(struct platform_device *pdev) 984 + { 985 + struct stm_drvdata *drvdata = dev_get_drvdata(&pdev->dev); 986 + 987 + if (WARN_ON(!drvdata)) 988 + return; 989 + 990 + __stm_remove(&pdev->dev); 991 + pm_runtime_disable(&pdev->dev); 992 + if (!IS_ERR_OR_NULL(drvdata->pclk)) 993 + clk_put(drvdata->pclk); 994 + } 995 + 996 + #ifdef CONFIG_ACPI 997 + static const struct acpi_device_id stm_acpi_ids[] = { 998 + {"ARMHC502", 0, 0, 0}, /* ARM CoreSight STM */ 999 + {}, 1000 + }; 1001 + MODULE_DEVICE_TABLE(acpi, stm_acpi_ids); 1002 + #endif 1003 + 1004 + static struct platform_driver stm_platform_driver = { 1005 + .probe = stm_platform_probe, 1006 + .remove_new = stm_platform_remove, 1007 + .driver = { 1008 + .name = "coresight-stm-platform", 1009 + .acpi_match_table = ACPI_PTR(stm_acpi_ids), 1010 + .suppress_bind_attrs = true, 1011 + .pm = &stm_dev_pm_ops, 1012 + }, 1013 + }; 1014 + 1015 + static int __init stm_init(void) 1016 + { 1017 + return coresight_init_driver("stm", &stm_driver, &stm_platform_driver); 1018 + } 1019 + 1020 + static void __exit stm_exit(void) 1021 + { 1022 + coresight_remove_driver(&stm_driver, &stm_platform_driver); 1023 + } 1024 + module_init(stm_init); 1025 + module_exit(stm_exit); 1000 1026 1001 1027 MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>"); 1002 1028 MODULE_DESCRIPTION("Arm CoreSight System Trace Macrocell driver");
+161 -20
drivers/hwtracing/coresight/coresight-tmc-core.c
··· 4 4 * Description: CoreSight Trace Memory Controller driver 5 5 */ 6 6 7 + #include <linux/acpi.h> 7 8 #include <linux/kernel.h> 8 9 #include <linux/init.h> 9 10 #include <linux/types.h> ··· 25 24 #include <linux/of.h> 26 25 #include <linux/coresight.h> 27 26 #include <linux/amba/bus.h> 27 + #include <linux/platform_device.h> 28 + #include <linux/acpi.h> 28 29 29 30 #include "coresight-priv.h" 30 31 #include "coresight-tmc.h" ··· 363 360 364 361 static inline bool tmc_etr_can_use_sg(struct device *dev) 365 362 { 366 - return fwnode_property_present(dev->fwnode, "arm,scatter-gather"); 363 + int ret; 364 + u8 val_u8; 365 + 366 + /* 367 + * Presence of the property 'arm,scatter-gather' is checked 368 + * on the platform for the feature support, rather than its 369 + * value. 370 + */ 371 + if (is_of_node(dev->fwnode)) { 372 + return fwnode_property_present(dev->fwnode, "arm,scatter-gather"); 373 + } else if (is_acpi_device_node(dev->fwnode)) { 374 + /* 375 + * TMC_DEVID_NOSCAT test in tmc_etr_setup_caps(), has already ensured 376 + * this property is only checked for Coresight SoC 400 TMC configured 377 + * as ETR. 378 + */ 379 + ret = fwnode_property_read_u8(dev->fwnode, "arm-armhc97c-sg-enable", &val_u8); 380 + if (!ret) 381 + return !!val_u8; 382 + 383 + if (fwnode_property_present(dev->fwnode, "arm,scatter-gather")) { 384 + pr_warn_once("Deprecated ACPI property - arm,scatter-gather\n"); 385 + return true; 386 + } 387 + } 388 + return false; 367 389 } 368 390 369 391 static inline bool tmc_etr_has_non_secure_access(struct tmc_drvdata *drvdata) ··· 398 370 return (auth & TMC_AUTH_NSID_MASK) == 0x3; 399 371 } 400 372 373 + static const struct amba_id tmc_ids[]; 374 + 401 375 /* Detect and initialise the capabilities of a TMC ETR */ 402 - static int tmc_etr_setup_caps(struct device *parent, u32 devid, void *dev_caps) 376 + static int tmc_etr_setup_caps(struct device *parent, u32 devid, 377 + struct csdev_access *access) 403 378 { 404 379 int rc; 405 - u32 dma_mask = 0; 380 + u32 tmc_pid, dma_mask = 0; 406 381 struct tmc_drvdata *drvdata = dev_get_drvdata(parent); 382 + void *dev_caps; 407 383 408 384 if (!tmc_etr_has_non_secure_access(drvdata)) 409 385 return -EACCES; 386 + 387 + tmc_pid = coresight_get_pid(access); 388 + dev_caps = coresight_get_uci_data_from_amba(tmc_ids, tmc_pid); 410 389 411 390 /* Set the unadvertised capabilities */ 412 391 tmc_etr_init_caps(drvdata, (u32)(unsigned long)dev_caps); ··· 472 437 return burst_size; 473 438 } 474 439 475 - static int tmc_probe(struct amba_device *adev, const struct amba_id *id) 440 + static int __tmc_probe(struct device *dev, struct resource *res) 476 441 { 477 442 int ret = 0; 478 443 u32 devid; 479 444 void __iomem *base; 480 - struct device *dev = &adev->dev; 481 445 struct coresight_platform_data *pdata = NULL; 482 - struct tmc_drvdata *drvdata; 483 - struct resource *res = &adev->res; 446 + struct tmc_drvdata *drvdata = dev_get_drvdata(dev); 484 447 struct coresight_desc desc = { 0 }; 485 448 struct coresight_dev_list *dev_list = NULL; 486 449 487 450 ret = -ENOMEM; 488 - drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); 489 - if (!drvdata) 490 - goto out; 491 - 492 - dev_set_drvdata(dev, drvdata); 493 451 494 452 /* Validity for the resource is already checked by the AMBA core */ 495 453 base = devm_ioremap_resource(dev, res); ··· 525 497 desc.type = CORESIGHT_DEV_TYPE_SINK; 526 498 desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_SYSMEM; 527 499 desc.ops = &tmc_etr_cs_ops; 528 - ret = tmc_etr_setup_caps(dev, devid, 529 - coresight_get_uci_data(id)); 500 + ret = tmc_etr_setup_caps(dev, devid, &desc.access); 530 501 if (ret) 531 502 goto out; 532 503 idr_init(&drvdata->idr); ··· 557 530 ret = PTR_ERR(pdata); 558 531 goto out; 559 532 } 560 - adev->dev.platform_data = pdata; 533 + dev->platform_data = pdata; 561 534 desc.pdata = pdata; 562 535 563 536 drvdata->csdev = coresight_register(&desc); ··· 572 545 ret = misc_register(&drvdata->miscdev); 573 546 if (ret) 574 547 coresight_unregister(drvdata->csdev); 575 - else 576 - pm_runtime_put(&adev->dev); 577 548 out: 549 + return ret; 550 + } 551 + 552 + static int tmc_probe(struct amba_device *adev, const struct amba_id *id) 553 + { 554 + struct tmc_drvdata *drvdata; 555 + int ret; 556 + 557 + drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL); 558 + if (!drvdata) 559 + return -ENOMEM; 560 + 561 + amba_set_drvdata(adev, drvdata); 562 + ret = __tmc_probe(&adev->dev, &adev->res); 563 + if (!ret) 564 + pm_runtime_put(&adev->dev); 565 + 578 566 return ret; 579 567 } 580 568 ··· 615 573 spin_unlock_irqrestore(&drvdata->spinlock, flags); 616 574 } 617 575 618 - static void tmc_remove(struct amba_device *adev) 576 + static void __tmc_remove(struct device *dev) 619 577 { 620 - struct tmc_drvdata *drvdata = dev_get_drvdata(&adev->dev); 578 + struct tmc_drvdata *drvdata = dev_get_drvdata(dev); 621 579 622 580 /* 623 581 * Since misc_open() holds a refcount on the f_ops, which is ··· 626 584 */ 627 585 misc_deregister(&drvdata->miscdev); 628 586 coresight_unregister(drvdata->csdev); 587 + } 588 + 589 + static void tmc_remove(struct amba_device *adev) 590 + { 591 + __tmc_remove(&adev->dev); 629 592 } 630 593 631 594 static const struct amba_id tmc_ids[] = { ··· 658 611 .id_table = tmc_ids, 659 612 }; 660 613 661 - module_amba_driver(tmc_driver); 614 + static int tmc_platform_probe(struct platform_device *pdev) 615 + { 616 + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 617 + struct tmc_drvdata *drvdata; 618 + int ret = 0; 619 + 620 + drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); 621 + if (!drvdata) 622 + return -ENOMEM; 623 + 624 + drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev); 625 + if (IS_ERR(drvdata->pclk)) 626 + return -ENODEV; 627 + 628 + dev_set_drvdata(&pdev->dev, drvdata); 629 + pm_runtime_get_noresume(&pdev->dev); 630 + pm_runtime_set_active(&pdev->dev); 631 + pm_runtime_enable(&pdev->dev); 632 + 633 + ret = __tmc_probe(&pdev->dev, res); 634 + pm_runtime_put(&pdev->dev); 635 + if (ret) 636 + pm_runtime_disable(&pdev->dev); 637 + 638 + return ret; 639 + } 640 + 641 + static void tmc_platform_remove(struct platform_device *pdev) 642 + { 643 + struct tmc_drvdata *drvdata = dev_get_drvdata(&pdev->dev); 644 + 645 + if (WARN_ON(!drvdata)) 646 + return; 647 + 648 + __tmc_remove(&pdev->dev); 649 + pm_runtime_disable(&pdev->dev); 650 + if (!IS_ERR_OR_NULL(drvdata->pclk)) 651 + clk_put(drvdata->pclk); 652 + } 653 + 654 + #ifdef CONFIG_PM 655 + static int tmc_runtime_suspend(struct device *dev) 656 + { 657 + struct tmc_drvdata *drvdata = dev_get_drvdata(dev); 658 + 659 + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) 660 + clk_disable_unprepare(drvdata->pclk); 661 + return 0; 662 + } 663 + 664 + static int tmc_runtime_resume(struct device *dev) 665 + { 666 + struct tmc_drvdata *drvdata = dev_get_drvdata(dev); 667 + 668 + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) 669 + clk_prepare_enable(drvdata->pclk); 670 + return 0; 671 + } 672 + #endif 673 + 674 + static const struct dev_pm_ops tmc_dev_pm_ops = { 675 + SET_RUNTIME_PM_OPS(tmc_runtime_suspend, tmc_runtime_resume, NULL) 676 + }; 677 + 678 + #ifdef CONFIG_ACPI 679 + static const struct acpi_device_id tmc_acpi_ids[] = { 680 + {"ARMHC501", 0, 0, 0}, /* ARM CoreSight ETR */ 681 + {"ARMHC97C", 0, 0, 0}, /* ARM CoreSight SoC-400 TMC, SoC-600 ETF/ETB */ 682 + {}, 683 + }; 684 + MODULE_DEVICE_TABLE(acpi, tmc_acpi_ids); 685 + #endif 686 + 687 + static struct platform_driver tmc_platform_driver = { 688 + .probe = tmc_platform_probe, 689 + .remove_new = tmc_platform_remove, 690 + .driver = { 691 + .name = "coresight-tmc-platform", 692 + .acpi_match_table = ACPI_PTR(tmc_acpi_ids), 693 + .suppress_bind_attrs = true, 694 + .pm = &tmc_dev_pm_ops, 695 + }, 696 + }; 697 + 698 + static int __init tmc_init(void) 699 + { 700 + return coresight_init_driver("tmc", &tmc_driver, &tmc_platform_driver); 701 + } 702 + 703 + static void __exit tmc_exit(void) 704 + { 705 + coresight_remove_driver(&tmc_driver, &tmc_platform_driver); 706 + } 707 + module_init(tmc_init); 708 + module_exit(tmc_exit); 662 709 663 710 MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>"); 664 711 MODULE_DESCRIPTION("Arm CoreSight Trace Memory Controller driver");
+2
drivers/hwtracing/coresight/coresight-tmc.h
··· 166 166 167 167 /** 168 168 * struct tmc_drvdata - specifics associated to an TMC component 169 + * @pclk: APB clock if present, otherwise NULL 169 170 * @base: memory mapped base address for this component. 170 171 * @csdev: component vitals needed by the framework. 171 172 * @miscdev: specifics to handle "/dev/xyz.tmc" entry. ··· 190 189 * @perf_buf: PERF buffer for ETR. 191 190 */ 192 191 struct tmc_drvdata { 192 + struct clk *pclk; 193 193 void __iomem *base; 194 194 struct coresight_device *csdev; 195 195 struct miscdevice miscdev;
+101 -19
drivers/hwtracing/coresight/coresight-tpiu.c
··· 5 5 * Description: CoreSight Trace Port Interface Unit driver 6 6 */ 7 7 8 - #include <linux/atomic.h> 9 - #include <linux/kernel.h> 10 - #include <linux/init.h> 11 - #include <linux/device.h> 12 - #include <linux/io.h> 13 - #include <linux/err.h> 14 - #include <linux/slab.h> 15 - #include <linux/pm_runtime.h> 16 - #include <linux/coresight.h> 8 + #include <linux/acpi.h> 17 9 #include <linux/amba/bus.h> 10 + #include <linux/atomic.h> 18 11 #include <linux/clk.h> 12 + #include <linux/coresight.h> 13 + #include <linux/device.h> 14 + #include <linux/err.h> 15 + #include <linux/init.h> 16 + #include <linux/io.h> 17 + #include <linux/kernel.h> 18 + #include <linux/platform_device.h> 19 + #include <linux/pm_runtime.h> 20 + #include <linux/slab.h> 19 21 20 22 #include "coresight-priv.h" 21 23 ··· 54 52 /* 55 53 * @base: memory mapped base address for this component. 56 54 * @atclk: optional clock for the core parts of the TPIU. 55 + * @pclk: APB clock if present, otherwise NULL 57 56 * @csdev: component vitals needed by the framework. 58 57 */ 59 58 struct tpiu_drvdata { 60 59 void __iomem *base; 61 60 struct clk *atclk; 61 + struct clk *pclk; 62 62 struct coresight_device *csdev; 63 63 spinlock_t spinlock; 64 64 }; ··· 126 122 .sink_ops = &tpiu_sink_ops, 127 123 }; 128 124 129 - static int tpiu_probe(struct amba_device *adev, const struct amba_id *id) 125 + static int __tpiu_probe(struct device *dev, struct resource *res) 130 126 { 131 127 int ret; 132 128 void __iomem *base; 133 - struct device *dev = &adev->dev; 134 129 struct coresight_platform_data *pdata = NULL; 135 130 struct tpiu_drvdata *drvdata; 136 - struct resource *res = &adev->res; 137 131 struct coresight_desc desc = { 0 }; 138 132 139 133 desc.name = coresight_alloc_device_name(&tpiu_devs, dev); ··· 144 142 145 143 spin_lock_init(&drvdata->spinlock); 146 144 147 - drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */ 145 + drvdata->atclk = devm_clk_get(dev, "atclk"); /* optional */ 148 146 if (!IS_ERR(drvdata->atclk)) { 149 147 ret = clk_prepare_enable(drvdata->atclk); 150 148 if (ret) 151 149 return ret; 152 150 } 151 + 152 + drvdata->pclk = coresight_get_enable_apb_pclk(dev); 153 + if (IS_ERR(drvdata->pclk)) 154 + return -ENODEV; 153 155 dev_set_drvdata(dev, drvdata); 154 156 155 157 /* Validity for the resource is already checked by the AMBA core */ ··· 179 173 desc.dev = dev; 180 174 drvdata->csdev = coresight_register(&desc); 181 175 182 - if (!IS_ERR(drvdata->csdev)) { 183 - pm_runtime_put(&adev->dev); 176 + if (!IS_ERR(drvdata->csdev)) 184 177 return 0; 185 - } 186 178 187 179 return PTR_ERR(drvdata->csdev); 188 180 } 189 181 190 - static void tpiu_remove(struct amba_device *adev) 182 + static int tpiu_probe(struct amba_device *adev, const struct amba_id *id) 191 183 { 192 - struct tpiu_drvdata *drvdata = dev_get_drvdata(&adev->dev); 184 + int ret; 185 + 186 + ret = __tpiu_probe(&adev->dev, &adev->res); 187 + if (!ret) 188 + pm_runtime_put(&adev->dev); 189 + return ret; 190 + } 191 + 192 + static void __tpiu_remove(struct device *dev) 193 + { 194 + struct tpiu_drvdata *drvdata = dev_get_drvdata(dev); 193 195 194 196 coresight_unregister(drvdata->csdev); 197 + } 198 + 199 + static void tpiu_remove(struct amba_device *adev) 200 + { 201 + __tpiu_remove(&adev->dev); 195 202 } 196 203 197 204 #ifdef CONFIG_PM ··· 215 196 if (drvdata && !IS_ERR(drvdata->atclk)) 216 197 clk_disable_unprepare(drvdata->atclk); 217 198 199 + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) 200 + clk_disable_unprepare(drvdata->pclk); 218 201 return 0; 219 202 } 220 203 ··· 227 206 if (drvdata && !IS_ERR(drvdata->atclk)) 228 207 clk_prepare_enable(drvdata->atclk); 229 208 209 + if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk)) 210 + clk_prepare_enable(drvdata->pclk); 230 211 return 0; 231 212 } 232 213 #endif ··· 268 245 .id_table = tpiu_ids, 269 246 }; 270 247 271 - module_amba_driver(tpiu_driver); 248 + static int tpiu_platform_probe(struct platform_device *pdev) 249 + { 250 + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 251 + int ret; 252 + 253 + pm_runtime_get_noresume(&pdev->dev); 254 + pm_runtime_set_active(&pdev->dev); 255 + pm_runtime_enable(&pdev->dev); 256 + 257 + ret = __tpiu_probe(&pdev->dev, res); 258 + pm_runtime_put(&pdev->dev); 259 + if (ret) 260 + pm_runtime_disable(&pdev->dev); 261 + 262 + return ret; 263 + } 264 + 265 + static void tpiu_platform_remove(struct platform_device *pdev) 266 + { 267 + struct tpiu_drvdata *drvdata = dev_get_drvdata(&pdev->dev); 268 + 269 + if (WARN_ON(!drvdata)) 270 + return; 271 + 272 + __tpiu_remove(&pdev->dev); 273 + pm_runtime_disable(&pdev->dev); 274 + if (!IS_ERR_OR_NULL(drvdata->pclk)) 275 + clk_put(drvdata->pclk); 276 + } 277 + 278 + #ifdef CONFIG_ACPI 279 + static const struct acpi_device_id tpiu_acpi_ids[] = { 280 + {"ARMHC979", 0, 0, 0}, /* ARM CoreSight TPIU */ 281 + {} 282 + }; 283 + MODULE_DEVICE_TABLE(acpi, tpiu_acpi_ids); 284 + #endif 285 + 286 + static struct platform_driver tpiu_platform_driver = { 287 + .probe = tpiu_platform_probe, 288 + .remove_new = tpiu_platform_remove, 289 + .driver = { 290 + .name = "coresight-tpiu-platform", 291 + .acpi_match_table = ACPI_PTR(tpiu_acpi_ids), 292 + .suppress_bind_attrs = true, 293 + .pm = &tpiu_dev_pm_ops, 294 + }, 295 + }; 296 + 297 + static int __init tpiu_init(void) 298 + { 299 + return coresight_init_driver("tpiu", &tpiu_driver, &tpiu_platform_driver); 300 + } 301 + 302 + static void __exit tpiu_exit(void) 303 + { 304 + coresight_remove_driver(&tpiu_driver, &tpiu_platform_driver); 305 + } 306 + module_init(tpiu_init); 307 + module_exit(tpiu_exit); 272 308 273 309 MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>"); 274 310 MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
+1
drivers/hwtracing/ptt/hisi_ptt.c
··· 1221 1221 1222 1222 hisi_ptt->hisi_ptt_pmu = (struct pmu) { 1223 1223 .module = THIS_MODULE, 1224 + .parent = &hisi_ptt->pdev->dev, 1224 1225 .capabilities = PERF_PMU_CAP_EXCLUSIVE | PERF_PMU_CAP_NO_EXCLUDE, 1225 1226 .task_ctx_nr = perf_sw_context, 1226 1227 .attr_groups = hisi_ptt_pmu_groups,
+6
include/linux/coresight.h
··· 12 12 #include <linux/io.h> 13 13 #include <linux/perf_event.h> 14 14 #include <linux/sched.h> 15 + #include <linux/platform_device.h> 15 16 16 17 /* Peripheral id registers (0xFD0-0xFEC) */ 17 18 #define CORESIGHT_PERIPHIDR4 0xfd0 ··· 659 658 enum coresight_dev_type type, 660 659 union coresight_dev_subtype subtype); 661 660 661 + int coresight_init_driver(const char *drv, struct amba_driver *amba_drv, 662 + struct platform_driver *pdev_drv); 663 + 664 + void coresight_remove_driver(struct amba_driver *amba_drv, 665 + struct platform_driver *pdev_drv); 662 666 #endif /* _LINUX_COREISGHT_H */