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>
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEuFy0byloRoXZHaWBxcXRZPKyBqEFAmYzcecACgkQxcXRZPKy
 BqEyrw//fsxpXrjt9Uz1QSmpEH+5eV//RQIO8vOOibihLrQYYMl8ZrwHp1n0lS0B
 Cj9P6MIRs8XztOBh5f0w57NoUOD9eJJ4/BdPRpixDPyZsm3acV/7JFMh1TIYQG6z
 ETlRGr5GRlLlx6VXkytMVfxRCtNlPR3PA3/fy5QR5BQ74ux+AlxuiX5krk6pEvak
 j8Vf35eNofqIDjNvr8ffY59kxDP+ULtiv+JWfAW+hzjjlQd+RxyamLUSJHr5Mh1N
 AqFjt+bqCVoT7MdtZoCrLX1b4gcgi1W/55Ph3ODdvy9vwErj2MpaNAW4829I5m1l
 dK5WmXFSQ/vb6UGj5laIu4ssZ0sMShu4jzatiGBBSo4FwAazSg2Lk3F6gNhXHBE2
 iyrU+Pr8mRnxh59FDtnldCD1ww0cUPZOQz29aNwNy1x52nkeEMOg2KYx3sXy/Sbx
 TK5qJ7Fv6DOEZ/fWDPxvZjKM8IbsvJI2XTL7WyyCt3hOT+bcdzQIwnlS8q+EdBL/
 zk/HAdb6/IA1vyg3kgmTCejC0EXwklME01UTs591HQ6U0iG+YxlklFFXLL9sw4Ij
 v6FVAbrtsgC8ov9UtmECqvjUlkZ5pwXkFU0php51R0MKvOWEU7vSxhtIjzvTumhu
 /lxyAQA+V112RWQS3nlxmUq3FWbqXIiFZSo1zvTavhxOtMVg06s=
 =yu6I
 -----END PGP SIGNATURE-----

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
  ...
This commit is contained in:
Greg Kroah-Hartman 2024-05-03 07:13:54 +02:00
commit d629cfcfed
23 changed files with 793 additions and 240 deletions

View File

@ -22,7 +22,7 @@ Contact: Mathieu Poirier <mathieu.poirier@linaro.org>
Description: (RW) Used in conjunction with @addr_idx. Specifies
characteristics about the address comparator being configure,
for example the access type, the kind of instruction to trace,
processor contect ID to trigger on, etc. Individual fields in
processor context ID to trigger on, etc. Individual fields in
the access type register may vary on the version of the trace
entity.

View File

@ -97,7 +97,7 @@ Date: August 2023
KernelVersion: 6.7
Contact: Anshuman Khandual <anshuman.khandual@arm.com>
Description: (Read) Shows all supported Coresight TMC-ETR buffer modes available
for the users to configure explicitly. This file is avaialble only
for the users to configure explicitly. This file is available only
for TMC ETR devices.
What: /sys/bus/coresight/devices/<memory_map>.tmc/buf_mode_preferred

View File

@ -244,7 +244,7 @@ KernelVersion 6.9
Contact: Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
Description:
(RW) Read or write the status of timestamp upon all interface.
Only value 0 and 1 can be written to this node. Set this node to 1 to requeset
Only value 0 and 1 can be written to this node. Set this node to 1 to request
timestamp to all trace packet.
Accepts only one of the 2 values - 0 or 1.
0 : Disable the timestamp of all trace packets.

View File

@ -1,4 +1,4 @@
What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune
What: /sys/bus/event_source/devices/hisi_ptt<sicl_id>_<core_id>/tune
Date: October 2022
KernelVersion: 6.1
Contact: Yicong Yang <yangyicong@hisilicon.com>
@ -8,7 +8,7 @@ Description: This directory contains files for tuning the PCIe link
See Documentation/trace/hisi-ptt.rst for more information.
What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune/qos_tx_cpl
What: /sys/bus/event_source/devices/hisi_ptt<sicl_id>_<core_id>/tune/qos_tx_cpl
Date: October 2022
KernelVersion: 6.1
Contact: Yicong Yang <yangyicong@hisilicon.com>
@ -18,7 +18,7 @@ Description: (RW) Controls the weight of Tx completion TLPs, which influence
will return an error, and out of range values will be converted
to 2. The value indicates a probable level of the event.
What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune/qos_tx_np
What: /sys/bus/event_source/devices/hisi_ptt<sicl_id>_<core_id>/tune/qos_tx_np
Date: October 2022
KernelVersion: 6.1
Contact: Yicong Yang <yangyicong@hisilicon.com>
@ -28,7 +28,7 @@ Description: (RW) Controls the weight of Tx non-posted TLPs, which influence
will return an error, and out of range values will be converted
to 2. The value indicates a probable level of the event.
What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune/qos_tx_p
What: /sys/bus/event_source/devices/hisi_ptt<sicl_id>_<core_id>/tune/qos_tx_p
Date: October 2022
KernelVersion: 6.1
Contact: Yicong Yang <yangyicong@hisilicon.com>
@ -38,7 +38,7 @@ Description: (RW) Controls the weight of Tx posted TLPs, which influence the
will return an error, and out of range values will be converted
to 2. The value indicates a probable level of the event.
What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune/rx_alloc_buf_level
What: /sys/bus/event_source/devices/hisi_ptt<sicl_id>_<core_id>/tune/rx_alloc_buf_level
Date: October 2022
KernelVersion: 6.1
Contact: Yicong Yang <yangyicong@hisilicon.com>
@ -49,7 +49,7 @@ Description: (RW) Control the allocated buffer watermark for inbound packets.
will return an error, and out of range values will be converted
to 2. The value indicates a probable level of the event.
What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune/tx_alloc_buf_level
What: /sys/bus/event_source/devices/hisi_ptt<sicl_id>_<core_id>/tune/tx_alloc_buf_level
Date: October 2022
KernelVersion: 6.1
Contact: Yicong Yang <yangyicong@hisilicon.com>

View File

@ -66,13 +66,11 @@ properties:
- const: apb_pclk
in-ports:
type: object
description: |
Input connections from TPDM to TPDA
$ref: /schemas/graph.yaml#/properties/ports
out-ports:
type: object
description: |
Output connections from the TPDA to legacy CoreSight trace bus.
$ref: /schemas/graph.yaml#/properties/ports
@ -97,33 +95,31 @@ examples:
# minimum tpda definition.
- |
tpda@6004000 {
compatible = "qcom,coresight-tpda", "arm,primecell";
reg = <0x6004000 0x1000>;
compatible = "qcom,coresight-tpda", "arm,primecell";
reg = <0x6004000 0x1000>;
clocks = <&aoss_qmp>;
clock-names = "apb_pclk";
clocks = <&aoss_qmp>;
clock-names = "apb_pclk";
in-ports {
#address-cells = <1>;
#size-cells = <0>;
in-ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
tpda_qdss_0_in_tpdm_dcc: endpoint {
remote-endpoint =
<&tpdm_dcc_out_tpda_qdss_0>;
};
remote-endpoint = <&tpdm_dcc_out_tpda_qdss_0>;
};
};
};
out-ports {
port {
tpda_qdss_out_funnel_in0: endpoint {
remote-endpoint =
<&funnel_in0_in_tpda_qdss>;
};
out-ports {
port {
tpda_qdss_out_funnel_in0: endpoint {
remote-endpoint = <&funnel_in0_in_tpda_qdss>;
};
};
};
};
};
...

View File

@ -40,7 +40,7 @@ IO dies (SICL, Super I/O Cluster), where there's one PCIe Root
Complex for each SICL.
::
/sys/devices/hisi_ptt<sicl_id>_<core_id>
/sys/bus/event_source/devices/hisi_ptt<sicl_id>_<core_id>
Tune
====
@ -53,7 +53,7 @@ Each event is presented as a file under $(PTT PMU dir)/tune, and
a simple open/read/write/close cycle will be used to tune the event.
::
$ cd /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune
$ cd /sys/bus/event_source/devices/hisi_ptt<sicl_id>_<core_id>/tune
$ ls
qos_tx_cpl qos_tx_np qos_tx_p
tx_path_rx_req_alloc_buf_level

View File

@ -9816,7 +9816,7 @@ M: Yicong Yang <yangyicong@hisilicon.com>
M: Jonathan Cameron <jonathan.cameron@huawei.com>
L: linux-kernel@vger.kernel.org
S: Maintained
F: Documentation/ABI/testing/sysfs-devices-hisi_ptt
F: Documentation/ABI/testing/sysfs-bus-event_source-devices-hisi_ptt
F: Documentation/trace/hisi-ptt.rst
F: drivers/hwtracing/ptt/
F: tools/perf/arch/arm64/util/hisi-ptt.c

View File

@ -22,14 +22,6 @@
static const struct acpi_device_id amba_id_list[] = {
{"ARMH0061", 0}, /* PL061 GPIO Device */
{"ARMH0330", 0}, /* ARM DMA Controller DMA-330 */
{"ARMHC501", 0}, /* ARM CoreSight ETR */
{"ARMHC502", 0}, /* ARM CoreSight STM */
{"ARMHC503", 0}, /* ARM CoreSight Debug */
{"ARMHC979", 0}, /* ARM CoreSight TPIU */
{"ARMHC97C", 0}, /* ARM CoreSight SoC-400 TMC, SoC-600 ETF/ETB */
{"ARMHC98D", 0}, /* ARM CoreSight Dynamic Replicator */
{"ARMHC9CA", 0}, /* ARM CoreSight CATU */
{"ARMHC9FF", 0}, /* ARM CoreSight Dynamic Funnel */
{"", 0},
};

View File

@ -7,11 +7,13 @@
* Author: Suzuki K Poulose <suzuki.poulose@arm.com>
*/
#include <linux/acpi.h>
#include <linux/amba/bus.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include "coresight-catu.h"
@ -502,28 +504,20 @@ static const struct coresight_ops catu_ops = {
.helper_ops = &catu_helper_ops,
};
static int catu_probe(struct amba_device *adev, const struct amba_id *id)
static int __catu_probe(struct device *dev, struct resource *res)
{
int ret = 0;
u32 dma_mask;
struct catu_drvdata *drvdata;
struct catu_drvdata *drvdata = dev_get_drvdata(dev);
struct coresight_desc catu_desc;
struct coresight_platform_data *pdata = NULL;
struct device *dev = &adev->dev;
void __iomem *base;
catu_desc.name = coresight_alloc_device_name(&catu_devs, dev);
if (!catu_desc.name)
return -ENOMEM;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata) {
ret = -ENOMEM;
goto out;
}
dev_set_drvdata(dev, drvdata);
base = devm_ioremap_resource(dev, &adev->res);
base = devm_ioremap_resource(dev, res);
if (IS_ERR(base)) {
ret = PTR_ERR(base);
goto out;
@ -567,19 +561,39 @@ static int catu_probe(struct amba_device *adev, const struct amba_id *id)
drvdata->csdev = coresight_register(&catu_desc);
if (IS_ERR(drvdata->csdev))
ret = PTR_ERR(drvdata->csdev);
else
pm_runtime_put(&adev->dev);
out:
return ret;
}
static void catu_remove(struct amba_device *adev)
static int catu_probe(struct amba_device *adev, const struct amba_id *id)
{
struct catu_drvdata *drvdata = dev_get_drvdata(&adev->dev);
struct catu_drvdata *drvdata;
int ret;
drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata)
return -ENOMEM;
amba_set_drvdata(adev, drvdata);
ret = __catu_probe(&adev->dev, &adev->res);
if (!ret)
pm_runtime_put(&adev->dev);
return ret;
}
static void __catu_remove(struct device *dev)
{
struct catu_drvdata *drvdata = dev_get_drvdata(dev);
coresight_unregister(drvdata->csdev);
}
static void catu_remove(struct amba_device *adev)
{
__catu_remove(&adev->dev);
}
static struct amba_id catu_ids[] = {
CS_AMBA_ID(0x000bb9ee),
{},
@ -598,13 +612,98 @@ static struct amba_driver catu_driver = {
.id_table = catu_ids,
};
static int catu_platform_probe(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct catu_drvdata *drvdata;
int ret = 0;
drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata)
return -ENOMEM;
drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
if (IS_ERR(drvdata->pclk))
return -ENODEV;
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
dev_set_drvdata(&pdev->dev, drvdata);
ret = __catu_probe(&pdev->dev, res);
pm_runtime_put(&pdev->dev);
if (ret) {
pm_runtime_disable(&pdev->dev);
if (!IS_ERR_OR_NULL(drvdata->pclk))
clk_put(drvdata->pclk);
}
return ret;
}
static void catu_platform_remove(struct platform_device *pdev)
{
struct catu_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
if (WARN_ON(!drvdata))
return;
__catu_remove(&pdev->dev);
pm_runtime_disable(&pdev->dev);
if (!IS_ERR_OR_NULL(drvdata->pclk))
clk_put(drvdata->pclk);
}
#ifdef CONFIG_PM
static int catu_runtime_suspend(struct device *dev)
{
struct catu_drvdata *drvdata = dev_get_drvdata(dev);
if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
clk_disable_unprepare(drvdata->pclk);
return 0;
}
static int catu_runtime_resume(struct device *dev)
{
struct catu_drvdata *drvdata = dev_get_drvdata(dev);
if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
clk_prepare_enable(drvdata->pclk);
return 0;
}
#endif
static const struct dev_pm_ops catu_dev_pm_ops = {
SET_RUNTIME_PM_OPS(catu_runtime_suspend, catu_runtime_resume, NULL)
};
#ifdef CONFIG_ACPI
static const struct acpi_device_id catu_acpi_ids[] = {
{"ARMHC9CA", 0, 0, 0}, /* ARM CoreSight CATU */
{},
};
MODULE_DEVICE_TABLE(acpi, catu_acpi_ids);
#endif
static struct platform_driver catu_platform_driver = {
.probe = catu_platform_probe,
.remove_new = catu_platform_remove,
.driver = {
.name = "coresight-catu-platform",
.acpi_match_table = ACPI_PTR(catu_acpi_ids),
.suppress_bind_attrs = true,
.pm = &catu_dev_pm_ops,
},
};
static int __init catu_init(void)
{
int ret;
ret = amba_driver_register(&catu_driver);
if (ret)
pr_info("Error registering catu driver\n");
ret = coresight_init_driver("catu", &catu_driver, &catu_platform_driver);
tmc_etr_set_catu_ops(&etr_catu_buf_ops);
return ret;
}
@ -612,7 +711,7 @@ static int __init catu_init(void)
static void __exit catu_exit(void)
{
tmc_etr_remove_catu_ops();
amba_driver_unregister(&catu_driver);
coresight_remove_driver(&catu_driver, &catu_platform_driver);
}
module_init(catu_init);

View File

@ -61,6 +61,7 @@
#define CATU_IRQEN_OFF 0x0
struct catu_drvdata {
struct clk *pclk;
void __iomem *base;
struct coresight_device *csdev;
int irq;

View File

@ -1398,6 +1398,35 @@ static void __exit coresight_exit(void)
module_init(coresight_init);
module_exit(coresight_exit);
int coresight_init_driver(const char *drv, struct amba_driver *amba_drv,
struct platform_driver *pdev_drv)
{
int ret;
ret = amba_driver_register(amba_drv);
if (ret) {
pr_err("%s: error registering AMBA driver\n", drv);
return ret;
}
ret = platform_driver_register(pdev_drv);
if (!ret)
return 0;
pr_err("%s: error registering platform driver\n", drv);
amba_driver_unregister(amba_drv);
return ret;
}
EXPORT_SYMBOL_GPL(coresight_init_driver);
void coresight_remove_driver(struct amba_driver *amba_drv,
struct platform_driver *pdev_drv)
{
amba_driver_unregister(amba_drv);
platform_driver_unregister(pdev_drv);
}
EXPORT_SYMBOL_GPL(coresight_remove_driver);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");

View File

@ -4,6 +4,7 @@
*
* Author: Leo Yan <leo.yan@linaro.org>
*/
#include <linux/acpi.h>
#include <linux/amba/bus.h>
#include <linux/coresight.h>
#include <linux/cpu.h>
@ -18,6 +19,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/panic_notifier.h>
#include <linux/platform_device.h>
#include <linux/pm_qos.h>
#include <linux/slab.h>
#include <linux/smp.h>
@ -84,6 +86,7 @@
#define DEBUG_WAIT_TIMEOUT 32000
struct debug_drvdata {
struct clk *pclk;
void __iomem *base;
struct device *dev;
int cpu;
@ -557,18 +560,12 @@ static void debug_func_exit(void)
debugfs_remove_recursive(debug_debugfs_dir);
}
static int debug_probe(struct amba_device *adev, const struct amba_id *id)
static int __debug_probe(struct device *dev, struct resource *res)
{
struct debug_drvdata *drvdata = dev_get_drvdata(dev);
void __iomem *base;
struct device *dev = &adev->dev;
struct debug_drvdata *drvdata;
struct resource *res = &adev->res;
int ret;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata)
return -ENOMEM;
drvdata->cpu = coresight_get_cpu(dev);
if (drvdata->cpu < 0)
return drvdata->cpu;
@ -579,10 +576,7 @@ static int debug_probe(struct amba_device *adev, const struct amba_id *id)
return -EBUSY;
}
drvdata->dev = &adev->dev;
amba_set_drvdata(adev, drvdata);
/* Validity for the resource is already checked by the AMBA core */
drvdata->dev = dev;
base = devm_ioremap_resource(dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
@ -629,10 +623,21 @@ err:
return ret;
}
static void debug_remove(struct amba_device *adev)
static int debug_probe(struct amba_device *adev, const struct amba_id *id)
{
struct device *dev = &adev->dev;
struct debug_drvdata *drvdata = amba_get_drvdata(adev);
struct debug_drvdata *drvdata;
drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata)
return -ENOMEM;
amba_set_drvdata(adev, drvdata);
return __debug_probe(&adev->dev, &adev->res);
}
static void __debug_remove(struct device *dev)
{
struct debug_drvdata *drvdata = dev_get_drvdata(dev);
per_cpu(debug_drvdata, drvdata->cpu) = NULL;
@ -646,6 +651,11 @@ static void debug_remove(struct amba_device *adev)
debug_func_exit();
}
static void debug_remove(struct amba_device *adev)
{
__debug_remove(&adev->dev);
}
static const struct amba_cs_uci_id uci_id_debug[] = {
{
/* CPU Debug UCI data */
@ -677,7 +687,102 @@ static struct amba_driver debug_driver = {
.id_table = debug_ids,
};
module_amba_driver(debug_driver);
static int debug_platform_probe(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct debug_drvdata *drvdata;
int ret = 0;
drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata)
return -ENOMEM;
drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
if (IS_ERR(drvdata->pclk))
return -ENODEV;
dev_set_drvdata(&pdev->dev, drvdata);
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
ret = __debug_probe(&pdev->dev, res);
if (ret) {
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
if (!IS_ERR_OR_NULL(drvdata->pclk))
clk_put(drvdata->pclk);
}
return ret;
}
static void debug_platform_remove(struct platform_device *pdev)
{
struct debug_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
if (WARN_ON(!drvdata))
return;
__debug_remove(&pdev->dev);
pm_runtime_disable(&pdev->dev);
if (!IS_ERR_OR_NULL(drvdata->pclk))
clk_put(drvdata->pclk);
}
#ifdef CONFIG_ACPI
static const struct acpi_device_id debug_platform_ids[] = {
{"ARMHC503", 0, 0, 0}, /* ARM CoreSight Debug */
{},
};
MODULE_DEVICE_TABLE(acpi, debug_platform_ids);
#endif
#ifdef CONFIG_PM
static int debug_runtime_suspend(struct device *dev)
{
struct debug_drvdata *drvdata = dev_get_drvdata(dev);
if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
clk_disable_unprepare(drvdata->pclk);
return 0;
}
static int debug_runtime_resume(struct device *dev)
{
struct debug_drvdata *drvdata = dev_get_drvdata(dev);
if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
clk_prepare_enable(drvdata->pclk);
return 0;
}
#endif
static const struct dev_pm_ops debug_dev_pm_ops = {
SET_RUNTIME_PM_OPS(debug_runtime_suspend, debug_runtime_resume, NULL)
};
static struct platform_driver debug_platform_driver = {
.probe = debug_platform_probe,
.remove_new = debug_platform_remove,
.driver = {
.name = "coresight-debug-platform",
.acpi_match_table = ACPI_PTR(debug_platform_ids),
.suppress_bind_attrs = true,
.pm = &debug_dev_pm_ops,
},
};
static int __init debug_init(void)
{
return coresight_init_driver("debug", &debug_driver, &debug_platform_driver);
}
static void __exit debug_exit(void)
{
coresight_remove_driver(&debug_driver, &debug_platform_driver);
}
module_init(debug_init);
module_exit(debug_exit);
MODULE_AUTHOR("Leo Yan <leo.yan@linaro.org>");
MODULE_DESCRIPTION("ARM Coresight CPU Debug Driver");

View File

@ -1240,6 +1240,8 @@ static void etm4_init_arch_data(void *info)
drvdata->nr_event = FIELD_GET(TRCIDR0_NUMEVENT_MASK, etmidr0);
/* QSUPP, bits[16:15] Q element support field */
drvdata->q_support = FIELD_GET(TRCIDR0_QSUPP_MASK, etmidr0);
if (drvdata->q_support)
drvdata->q_filt = !!(etmidr0 & TRCIDR0_QFILT);
/* TSSIZE, bits[28:24] Global timestamp size field */
drvdata->ts_size = FIELD_GET(TRCIDR0_TSSIZE_MASK, etmidr0);
@ -1732,16 +1734,14 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata)
state->trcccctlr = etm4x_read32(csa, TRCCCCTLR);
state->trcbbctlr = etm4x_read32(csa, TRCBBCTLR);
state->trctraceidr = etm4x_read32(csa, TRCTRACEIDR);
state->trcqctlr = etm4x_read32(csa, TRCQCTLR);
if (drvdata->q_filt)
state->trcqctlr = etm4x_read32(csa, TRCQCTLR);
state->trcvictlr = etm4x_read32(csa, TRCVICTLR);
state->trcviiectlr = etm4x_read32(csa, TRCVIIECTLR);
state->trcvissctlr = etm4x_read32(csa, TRCVISSCTLR);
if (drvdata->nr_pe_cmp)
state->trcvipcssctlr = etm4x_read32(csa, TRCVIPCSSCTLR);
state->trcvdctlr = etm4x_read32(csa, TRCVDCTLR);
state->trcvdsacctlr = etm4x_read32(csa, TRCVDSACCTLR);
state->trcvdarcctlr = etm4x_read32(csa, TRCVDARCCTLR);
for (i = 0; i < drvdata->nrseqstate - 1; i++)
state->trcseqevr[i] = etm4x_read32(csa, TRCSEQEVRn(i));
@ -1758,7 +1758,8 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata)
state->trccntvr[i] = etm4x_read32(csa, TRCCNTVRn(i));
}
for (i = 0; i < drvdata->nr_resource * 2; i++)
/* Resource selector pair 0 is reserved */
for (i = 2; i < drvdata->nr_resource * 2; i++)
state->trcrsctlr[i] = etm4x_read32(csa, TRCRSCTLRn(i));
for (i = 0; i < drvdata->nr_ss_cmp; i++) {
@ -1843,8 +1844,10 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata)
{
int i;
struct etmv4_save_state *state = drvdata->save_state;
struct csdev_access tmp_csa = CSDEV_ACCESS_IOMEM(drvdata->base);
struct csdev_access *csa = &tmp_csa;
struct csdev_access *csa = &drvdata->csdev->access;
if (WARN_ON(!drvdata->csdev))
return;
etm4_cs_unlock(drvdata, csa);
etm4x_relaxed_write32(csa, state->trcclaimset, TRCCLAIMSET);
@ -1863,16 +1866,14 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata)
etm4x_relaxed_write32(csa, state->trcccctlr, TRCCCCTLR);
etm4x_relaxed_write32(csa, state->trcbbctlr, TRCBBCTLR);
etm4x_relaxed_write32(csa, state->trctraceidr, TRCTRACEIDR);
etm4x_relaxed_write32(csa, state->trcqctlr, TRCQCTLR);
if (drvdata->q_filt)
etm4x_relaxed_write32(csa, state->trcqctlr, TRCQCTLR);
etm4x_relaxed_write32(csa, state->trcvictlr, TRCVICTLR);
etm4x_relaxed_write32(csa, state->trcviiectlr, TRCVIIECTLR);
etm4x_relaxed_write32(csa, state->trcvissctlr, TRCVISSCTLR);
if (drvdata->nr_pe_cmp)
etm4x_relaxed_write32(csa, state->trcvipcssctlr, TRCVIPCSSCTLR);
etm4x_relaxed_write32(csa, state->trcvdctlr, TRCVDCTLR);
etm4x_relaxed_write32(csa, state->trcvdsacctlr, TRCVDSACCTLR);
etm4x_relaxed_write32(csa, state->trcvdarcctlr, TRCVDARCCTLR);
for (i = 0; i < drvdata->nrseqstate - 1; i++)
etm4x_relaxed_write32(csa, state->trcseqevr[i], TRCSEQEVRn(i));
@ -1889,7 +1890,8 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata)
etm4x_relaxed_write32(csa, state->trccntvr[i], TRCCNTVRn(i));
}
for (i = 0; i < drvdata->nr_resource * 2; i++)
/* Resource selector pair 0 is reserved */
for (i = 2; i < drvdata->nr_resource * 2; i++)
etm4x_relaxed_write32(csa, state->trcrsctlr[i], TRCRSCTLRn(i));
for (i = 0; i < drvdata->nr_ss_cmp; i++) {
@ -2213,6 +2215,9 @@ static int etm4_probe_platform_dev(struct platform_device *pdev)
ret = etm4_probe(&pdev->dev);
pm_runtime_put(&pdev->dev);
if (ret)
pm_runtime_disable(&pdev->dev);
return ret;
}

View File

@ -43,9 +43,6 @@
#define TRCVIIECTLR 0x084
#define TRCVISSCTLR 0x088
#define TRCVIPCSSCTLR 0x08C
#define TRCVDCTLR 0x0A0
#define TRCVDSACCTLR 0x0A4
#define TRCVDARCCTLR 0x0A8
/* Derived resources registers */
#define TRCSEQEVRn(n) (0x100 + (n * 4)) /* n = 0-2 */
#define TRCSEQRSTEVR 0x118
@ -90,9 +87,6 @@
/* Address Comparator registers n = 0-15 */
#define TRCACVRn(n) (0x400 + (n * 8))
#define TRCACATRn(n) (0x480 + (n * 8))
/* Data Value Comparator Value registers, n = 0-7 */
#define TRCDVCVRn(n) (0x500 + (n * 16))
#define TRCDVCMRn(n) (0x580 + (n * 16))
/* ContextID/Virtual ContextID comparators, n = 0-7 */
#define TRCCIDCVRn(n) (0x600 + (n * 8))
#define TRCVMIDCVRn(n) (0x640 + (n * 8))
@ -141,6 +135,7 @@
#define TRCIDR0_TRCCCI BIT(7)
#define TRCIDR0_RETSTACK BIT(9)
#define TRCIDR0_NUMEVENT_MASK GENMASK(11, 10)
#define TRCIDR0_QFILT BIT(14)
#define TRCIDR0_QSUPP_MASK GENMASK(16, 15)
#define TRCIDR0_TSSIZE_MASK GENMASK(28, 24)
@ -272,9 +267,6 @@
/* List of registers accessible via System instructions */
#define ETM4x_ONLY_SYSREG_LIST(op, val) \
CASE_##op((val), TRCPROCSELR) \
CASE_##op((val), TRCVDCTLR) \
CASE_##op((val), TRCVDSACCTLR) \
CASE_##op((val), TRCVDARCCTLR) \
CASE_##op((val), TRCOSLAR)
#define ETM_COMMON_SYSREG_LIST(op, val) \
@ -422,22 +414,6 @@
CASE_##op((val), TRCACATRn(13)) \
CASE_##op((val), TRCACATRn(14)) \
CASE_##op((val), TRCACATRn(15)) \
CASE_##op((val), TRCDVCVRn(0)) \
CASE_##op((val), TRCDVCVRn(1)) \
CASE_##op((val), TRCDVCVRn(2)) \
CASE_##op((val), TRCDVCVRn(3)) \
CASE_##op((val), TRCDVCVRn(4)) \
CASE_##op((val), TRCDVCVRn(5)) \
CASE_##op((val), TRCDVCVRn(6)) \
CASE_##op((val), TRCDVCVRn(7)) \
CASE_##op((val), TRCDVCMRn(0)) \
CASE_##op((val), TRCDVCMRn(1)) \
CASE_##op((val), TRCDVCMRn(2)) \
CASE_##op((val), TRCDVCMRn(3)) \
CASE_##op((val), TRCDVCMRn(4)) \
CASE_##op((val), TRCDVCMRn(5)) \
CASE_##op((val), TRCDVCMRn(6)) \
CASE_##op((val), TRCDVCMRn(7)) \
CASE_##op((val), TRCCIDCVRn(0)) \
CASE_##op((val), TRCCIDCVRn(1)) \
CASE_##op((val), TRCCIDCVRn(2)) \
@ -907,9 +883,6 @@ struct etmv4_save_state {
u32 trcviiectlr;
u32 trcvissctlr;
u32 trcvipcssctlr;
u32 trcvdctlr;
u32 trcvdsacctlr;
u32 trcvdarcctlr;
u32 trcseqevr[ETM_MAX_SEQ_STATES];
u32 trcseqrstevr;
@ -982,6 +955,7 @@ struct etmv4_save_state {
* @os_unlock: True if access to management registers is allowed.
* @instrp0: Tracing of load and store instructions
* as P0 elements is supported.
* @q_filt: Q element filtering support, if Q elements are supported.
* @trcbb: Indicates if the trace unit supports branch broadcast tracing.
* @trccond: If the trace unit supports conditional
* instruction tracing.
@ -1044,6 +1018,7 @@ struct etmv4_drvdata {
bool boot_enable;
bool os_unlock;
bool instrp0;
bool q_filt;
bool trcbb;
bool trccond;
bool retstack;

View File

@ -36,6 +36,7 @@ DEFINE_CORESIGHT_DEVLIST(funnel_devs, "funnel");
* struct funnel_drvdata - specifics associated to a funnel component
* @base: memory mapped base address for this component.
* @atclk: optional clock for the core parts of the funnel.
* @pclk: APB clock if present, otherwise NULL
* @csdev: component vitals needed by the framework.
* @priority: port selection order.
* @spinlock: serialize enable/disable operations.
@ -43,6 +44,7 @@ DEFINE_CORESIGHT_DEVLIST(funnel_devs, "funnel");
struct funnel_drvdata {
void __iomem *base;
struct clk *atclk;
struct clk *pclk;
struct coresight_device *csdev;
unsigned long priority;
spinlock_t spinlock;
@ -236,6 +238,10 @@ static int funnel_probe(struct device *dev, struct resource *res)
return ret;
}
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
if (IS_ERR(drvdata->pclk))
return -ENODEV;
/*
* Map the device base for dynamic-funnel, which has been
* validated by AMBA core.
@ -272,12 +278,13 @@ static int funnel_probe(struct device *dev, struct resource *res)
goto out_disable_clk;
}
pm_runtime_put(dev);
ret = 0;
out_disable_clk:
if (ret && !IS_ERR_OR_NULL(drvdata->atclk))
clk_disable_unprepare(drvdata->atclk);
if (ret && !IS_ERR_OR_NULL(drvdata->pclk))
clk_disable_unprepare(drvdata->pclk);
return ret;
}
@ -298,6 +305,9 @@ static int funnel_runtime_suspend(struct device *dev)
if (drvdata && !IS_ERR(drvdata->atclk))
clk_disable_unprepare(drvdata->atclk);
if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
clk_disable_unprepare(drvdata->pclk);
return 0;
}
@ -308,6 +318,8 @@ static int funnel_runtime_resume(struct device *dev)
if (drvdata && !IS_ERR(drvdata->atclk))
clk_prepare_enable(drvdata->atclk);
if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
clk_prepare_enable(drvdata->pclk);
return 0;
}
#endif
@ -316,55 +328,61 @@ static const struct dev_pm_ops funnel_dev_pm_ops = {
SET_RUNTIME_PM_OPS(funnel_runtime_suspend, funnel_runtime_resume, NULL)
};
static int static_funnel_probe(struct platform_device *pdev)
static int funnel_platform_probe(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
int ret;
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
/* Static funnel do not have programming base */
ret = funnel_probe(&pdev->dev, NULL);
if (ret) {
pm_runtime_put_noidle(&pdev->dev);
ret = funnel_probe(&pdev->dev, res);
pm_runtime_put(&pdev->dev);
if (ret)
pm_runtime_disable(&pdev->dev);
}
return ret;
}
static void static_funnel_remove(struct platform_device *pdev)
static void funnel_platform_remove(struct platform_device *pdev)
{
struct funnel_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
if (WARN_ON(!drvdata))
return;
funnel_remove(&pdev->dev);
pm_runtime_disable(&pdev->dev);
if (!IS_ERR_OR_NULL(drvdata->pclk))
clk_put(drvdata->pclk);
}
static const struct of_device_id static_funnel_match[] = {
static const struct of_device_id funnel_match[] = {
{.compatible = "arm,coresight-static-funnel"},
{}
};
MODULE_DEVICE_TABLE(of, static_funnel_match);
MODULE_DEVICE_TABLE(of, funnel_match);
#ifdef CONFIG_ACPI
static const struct acpi_device_id static_funnel_ids[] = {
{"ARMHC9FE", 0, 0, 0},
static const struct acpi_device_id funnel_acpi_ids[] = {
{"ARMHC9FE", 0, 0, 0}, /* ARM Coresight Static Funnel */
{"ARMHC9FF", 0, 0, 0}, /* ARM CoreSight Dynamic Funnel */
{},
};
MODULE_DEVICE_TABLE(acpi, static_funnel_ids);
MODULE_DEVICE_TABLE(acpi, funnel_acpi_ids);
#endif
static struct platform_driver static_funnel_driver = {
.probe = static_funnel_probe,
.remove_new = static_funnel_remove,
.driver = {
.name = "coresight-static-funnel",
static struct platform_driver funnel_driver = {
.probe = funnel_platform_probe,
.remove_new = funnel_platform_remove,
.driver = {
.name = "coresight-funnel",
/* THIS_MODULE is taken care of by platform_driver_register() */
.of_match_table = static_funnel_match,
.acpi_match_table = ACPI_PTR(static_funnel_ids),
.of_match_table = funnel_match,
.acpi_match_table = ACPI_PTR(funnel_acpi_ids),
.pm = &funnel_dev_pm_ops,
.suppress_bind_attrs = true,
},
@ -373,7 +391,13 @@ static struct platform_driver static_funnel_driver = {
static int dynamic_funnel_probe(struct amba_device *adev,
const struct amba_id *id)
{
return funnel_probe(&adev->dev, &adev->res);
int ret;
ret = funnel_probe(&adev->dev, &adev->res);
if (!ret)
pm_runtime_put(&adev->dev);
return ret;
}
static void dynamic_funnel_remove(struct amba_device *adev)
@ -410,27 +434,12 @@ static struct amba_driver dynamic_funnel_driver = {
static int __init funnel_init(void)
{
int ret;
ret = platform_driver_register(&static_funnel_driver);
if (ret) {
pr_info("Error registering platform driver\n");
return ret;
}
ret = amba_driver_register(&dynamic_funnel_driver);
if (ret) {
pr_info("Error registering amba driver\n");
platform_driver_unregister(&static_funnel_driver);
}
return ret;
return coresight_init_driver("funnel", &dynamic_funnel_driver, &funnel_driver);
}
static void __exit funnel_exit(void)
{
platform_driver_unregister(&static_funnel_driver);
amba_driver_unregister(&dynamic_funnel_driver);
coresight_remove_driver(&dynamic_funnel_driver, &funnel_driver);
}
module_init(funnel_init);

View File

@ -222,6 +222,16 @@ static inline void *coresight_get_uci_data(const struct amba_id *id)
return uci_id->data;
}
static inline void *coresight_get_uci_data_from_amba(const struct amba_id *table, u32 pid)
{
while (table->mask) {
if ((pid & table->mask) == table->id)
return coresight_get_uci_data(table);
table++;
};
return NULL;
}
void coresight_release_platform_data(struct coresight_device *csdev,
struct device *dev,
struct coresight_platform_data *pdata);

View File

@ -31,6 +31,7 @@ DEFINE_CORESIGHT_DEVLIST(replicator_devs, "replicator");
* @base: memory mapped base address for this component. Also indicates
* whether this one is programmable or not.
* @atclk: optional clock for the core parts of the replicator.
* @pclk: APB clock if present, otherwise NULL
* @csdev: component vitals needed by the framework
* @spinlock: serialize enable/disable operations.
* @check_idfilter_val: check if the context is lost upon clock removal.
@ -38,6 +39,7 @@ DEFINE_CORESIGHT_DEVLIST(replicator_devs, "replicator");
struct replicator_drvdata {
void __iomem *base;
struct clk *atclk;
struct clk *pclk;
struct coresight_device *csdev;
spinlock_t spinlock;
bool check_idfilter_val;
@ -243,6 +245,10 @@ static int replicator_probe(struct device *dev, struct resource *res)
return ret;
}
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
if (IS_ERR(drvdata->pclk))
return -ENODEV;
/*
* Map the device base for dynamic-replicator, which has been
* validated by AMBA core
@ -285,11 +291,12 @@ static int replicator_probe(struct device *dev, struct resource *res)
}
replicator_reset(drvdata);
pm_runtime_put(dev);
out_disable_clk:
if (ret && !IS_ERR_OR_NULL(drvdata->atclk))
clk_disable_unprepare(drvdata->atclk);
if (ret && !IS_ERR_OR_NULL(drvdata->pclk))
clk_disable_unprepare(drvdata->pclk);
return ret;
}
@ -301,29 +308,34 @@ static int replicator_remove(struct device *dev)
return 0;
}
static int static_replicator_probe(struct platform_device *pdev)
static int replicator_platform_probe(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
int ret;
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
/* Static replicators do not have programming base */
ret = replicator_probe(&pdev->dev, NULL);
if (ret) {
pm_runtime_put_noidle(&pdev->dev);
ret = replicator_probe(&pdev->dev, res);
pm_runtime_put(&pdev->dev);
if (ret)
pm_runtime_disable(&pdev->dev);
}
return ret;
}
static void static_replicator_remove(struct platform_device *pdev)
static void replicator_platform_remove(struct platform_device *pdev)
{
struct replicator_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
if (WARN_ON(!drvdata))
return;
replicator_remove(&pdev->dev);
pm_runtime_disable(&pdev->dev);
if (!IS_ERR_OR_NULL(drvdata->pclk))
clk_put(drvdata->pclk);
}
#ifdef CONFIG_PM
@ -334,6 +346,8 @@ static int replicator_runtime_suspend(struct device *dev)
if (drvdata && !IS_ERR(drvdata->atclk))
clk_disable_unprepare(drvdata->atclk);
if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
clk_disable_unprepare(drvdata->pclk);
return 0;
}
@ -344,6 +358,8 @@ static int replicator_runtime_resume(struct device *dev)
if (drvdata && !IS_ERR(drvdata->atclk))
clk_prepare_enable(drvdata->atclk);
if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
clk_prepare_enable(drvdata->pclk);
return 0;
}
#endif
@ -353,31 +369,32 @@ static const struct dev_pm_ops replicator_dev_pm_ops = {
replicator_runtime_resume, NULL)
};
static const struct of_device_id static_replicator_match[] = {
static const struct of_device_id replicator_match[] = {
{.compatible = "arm,coresight-replicator"},
{.compatible = "arm,coresight-static-replicator"},
{}
};
MODULE_DEVICE_TABLE(of, static_replicator_match);
MODULE_DEVICE_TABLE(of, replicator_match);
#ifdef CONFIG_ACPI
static const struct acpi_device_id static_replicator_acpi_ids[] = {
static const struct acpi_device_id replicator_acpi_ids[] = {
{"ARMHC985", 0, 0, 0}, /* ARM CoreSight Static Replicator */
{"ARMHC98D", 0, 0, 0}, /* ARM CoreSight Dynamic Replicator */
{}
};
MODULE_DEVICE_TABLE(acpi, static_replicator_acpi_ids);
MODULE_DEVICE_TABLE(acpi, replicator_acpi_ids);
#endif
static struct platform_driver static_replicator_driver = {
.probe = static_replicator_probe,
.remove_new = static_replicator_remove,
static struct platform_driver replicator_driver = {
.probe = replicator_platform_probe,
.remove_new = replicator_platform_remove,
.driver = {
.name = "coresight-static-replicator",
.name = "coresight-replicator",
/* THIS_MODULE is taken care of by platform_driver_register() */
.of_match_table = of_match_ptr(static_replicator_match),
.acpi_match_table = ACPI_PTR(static_replicator_acpi_ids),
.of_match_table = of_match_ptr(replicator_match),
.acpi_match_table = ACPI_PTR(replicator_acpi_ids),
.pm = &replicator_dev_pm_ops,
.suppress_bind_attrs = true,
},
@ -386,7 +403,13 @@ static struct platform_driver static_replicator_driver = {
static int dynamic_replicator_probe(struct amba_device *adev,
const struct amba_id *id)
{
return replicator_probe(&adev->dev, &adev->res);
int ret;
ret = replicator_probe(&adev->dev, &adev->res);
if (!ret)
pm_runtime_put(&adev->dev);
return ret;
}
static void dynamic_replicator_remove(struct amba_device *adev)
@ -416,27 +439,12 @@ static struct amba_driver dynamic_replicator_driver = {
static int __init replicator_init(void)
{
int ret;
ret = platform_driver_register(&static_replicator_driver);
if (ret) {
pr_info("Error registering platform driver\n");
return ret;
}
ret = amba_driver_register(&dynamic_replicator_driver);
if (ret) {
pr_info("Error registering amba driver\n");
platform_driver_unregister(&static_replicator_driver);
}
return ret;
return coresight_init_driver("replicator", &dynamic_replicator_driver, &replicator_driver);
}
static void __exit replicator_exit(void)
{
platform_driver_unregister(&static_replicator_driver);
amba_driver_unregister(&dynamic_replicator_driver);
coresight_remove_driver(&dynamic_replicator_driver, &replicator_driver);
}
module_init(replicator_init);

View File

@ -29,6 +29,7 @@
#include <linux/perf_event.h>
#include <linux/pm_runtime.h>
#include <linux/stm.h>
#include <linux/platform_device.h>
#include "coresight-priv.h"
#include "coresight-trace-id.h"
@ -115,6 +116,7 @@ DEFINE_CORESIGHT_DEVLIST(stm_devs, "stm");
* struct stm_drvdata - specifics associated to an STM component
* @base: memory mapped base address for this component.
* @atclk: optional clock for the core parts of the STM.
* @pclk: APB clock if present, otherwise NULL
* @csdev: component vitals needed by the framework.
* @spinlock: only one at a time pls.
* @chs: the channels accociated to this STM.
@ -131,6 +133,7 @@ DEFINE_CORESIGHT_DEVLIST(stm_devs, "stm");
struct stm_drvdata {
void __iomem *base;
struct clk *atclk;
struct clk *pclk;
struct coresight_device *csdev;
spinlock_t spinlock;
struct channel_space chs;
@ -800,14 +803,22 @@ static void stm_init_generic_data(struct stm_drvdata *drvdata,
drvdata->stm.set_options = stm_generic_set_options;
}
static int stm_probe(struct amba_device *adev, const struct amba_id *id)
static const struct amba_id stm_ids[];
static char *stm_csdev_name(struct coresight_device *csdev)
{
u32 stm_pid = coresight_get_pid(&csdev->access);
void *uci_data = coresight_get_uci_data_from_amba(stm_ids, stm_pid);
return uci_data ? (char *)uci_data : "STM";
}
static int __stm_probe(struct device *dev, struct resource *res)
{
int ret, trace_id;
void __iomem *base;
struct device *dev = &adev->dev;
struct coresight_platform_data *pdata = NULL;
struct stm_drvdata *drvdata;
struct resource *res = &adev->res;
struct resource ch_res;
struct coresight_desc desc = { 0 };
@ -819,12 +830,16 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id)
if (!drvdata)
return -ENOMEM;
drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */
drvdata->atclk = devm_clk_get(dev, "atclk"); /* optional */
if (!IS_ERR(drvdata->atclk)) {
ret = clk_prepare_enable(drvdata->atclk);
if (ret)
return ret;
}
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
if (IS_ERR(drvdata->pclk))
return -ENODEV;
dev_set_drvdata(dev, drvdata);
base = devm_ioremap_resource(dev, res);
@ -872,7 +887,7 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id)
ret = PTR_ERR(pdata);
goto stm_unregister;
}
adev->dev.platform_data = pdata;
dev->platform_data = pdata;
desc.type = CORESIGHT_DEV_TYPE_SOURCE;
desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE;
@ -893,10 +908,8 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id)
}
drvdata->traceid = (u8)trace_id;
pm_runtime_put(&adev->dev);
dev_info(&drvdata->csdev->dev, "%s initialized\n",
(char *)coresight_get_uci_data(id));
stm_csdev_name(drvdata->csdev));
return 0;
cs_unregister:
@ -907,9 +920,20 @@ stm_unregister:
return ret;
}
static void stm_remove(struct amba_device *adev)
static int stm_probe(struct amba_device *adev, const struct amba_id *id)
{
struct stm_drvdata *drvdata = dev_get_drvdata(&adev->dev);
int ret;
ret = __stm_probe(&adev->dev, &adev->res);
if (!ret)
pm_runtime_put(&adev->dev);
return ret;
}
static void __stm_remove(struct device *dev)
{
struct stm_drvdata *drvdata = dev_get_drvdata(dev);
coresight_trace_id_put_system_id(drvdata->traceid);
coresight_unregister(drvdata->csdev);
@ -917,6 +941,11 @@ static void stm_remove(struct amba_device *adev)
stm_unregister_device(&drvdata->stm);
}
static void stm_remove(struct amba_device *adev)
{
__stm_remove(&adev->dev);
}
#ifdef CONFIG_PM
static int stm_runtime_suspend(struct device *dev)
{
@ -925,6 +954,8 @@ static int stm_runtime_suspend(struct device *dev)
if (drvdata && !IS_ERR(drvdata->atclk))
clk_disable_unprepare(drvdata->atclk);
if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
clk_disable_unprepare(drvdata->pclk);
return 0;
}
@ -935,6 +966,8 @@ static int stm_runtime_resume(struct device *dev)
if (drvdata && !IS_ERR(drvdata->atclk))
clk_prepare_enable(drvdata->atclk);
if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
clk_prepare_enable(drvdata->pclk);
return 0;
}
#endif
@ -963,7 +996,66 @@ static struct amba_driver stm_driver = {
.id_table = stm_ids,
};
module_amba_driver(stm_driver);
static int stm_platform_probe(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
int ret = 0;
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
ret = __stm_probe(&pdev->dev, res);
pm_runtime_put(&pdev->dev);
if (ret)
pm_runtime_disable(&pdev->dev);
return ret;
}
static void stm_platform_remove(struct platform_device *pdev)
{
struct stm_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
if (WARN_ON(!drvdata))
return;
__stm_remove(&pdev->dev);
pm_runtime_disable(&pdev->dev);
if (!IS_ERR_OR_NULL(drvdata->pclk))
clk_put(drvdata->pclk);
}
#ifdef CONFIG_ACPI
static const struct acpi_device_id stm_acpi_ids[] = {
{"ARMHC502", 0, 0, 0}, /* ARM CoreSight STM */
{},
};
MODULE_DEVICE_TABLE(acpi, stm_acpi_ids);
#endif
static struct platform_driver stm_platform_driver = {
.probe = stm_platform_probe,
.remove_new = stm_platform_remove,
.driver = {
.name = "coresight-stm-platform",
.acpi_match_table = ACPI_PTR(stm_acpi_ids),
.suppress_bind_attrs = true,
.pm = &stm_dev_pm_ops,
},
};
static int __init stm_init(void)
{
return coresight_init_driver("stm", &stm_driver, &stm_platform_driver);
}
static void __exit stm_exit(void)
{
coresight_remove_driver(&stm_driver, &stm_platform_driver);
}
module_init(stm_init);
module_exit(stm_exit);
MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
MODULE_DESCRIPTION("Arm CoreSight System Trace Macrocell driver");

View File

@ -4,6 +4,7 @@
* Description: CoreSight Trace Memory Controller driver
*/
#include <linux/acpi.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/types.h>
@ -24,6 +25,8 @@
#include <linux/of.h>
#include <linux/coresight.h>
#include <linux/amba/bus.h>
#include <linux/platform_device.h>
#include <linux/acpi.h>
#include "coresight-priv.h"
#include "coresight-tmc.h"
@ -360,7 +363,32 @@ static const struct attribute_group *coresight_etr_groups[] = {
static inline bool tmc_etr_can_use_sg(struct device *dev)
{
return fwnode_property_present(dev->fwnode, "arm,scatter-gather");
int ret;
u8 val_u8;
/*
* Presence of the property 'arm,scatter-gather' is checked
* on the platform for the feature support, rather than its
* value.
*/
if (is_of_node(dev->fwnode)) {
return fwnode_property_present(dev->fwnode, "arm,scatter-gather");
} else if (is_acpi_device_node(dev->fwnode)) {
/*
* TMC_DEVID_NOSCAT test in tmc_etr_setup_caps(), has already ensured
* this property is only checked for Coresight SoC 400 TMC configured
* as ETR.
*/
ret = fwnode_property_read_u8(dev->fwnode, "arm-armhc97c-sg-enable", &val_u8);
if (!ret)
return !!val_u8;
if (fwnode_property_present(dev->fwnode, "arm,scatter-gather")) {
pr_warn_once("Deprecated ACPI property - arm,scatter-gather\n");
return true;
}
}
return false;
}
static inline bool tmc_etr_has_non_secure_access(struct tmc_drvdata *drvdata)
@ -370,16 +398,23 @@ static inline bool tmc_etr_has_non_secure_access(struct tmc_drvdata *drvdata)
return (auth & TMC_AUTH_NSID_MASK) == 0x3;
}
static const struct amba_id tmc_ids[];
/* Detect and initialise the capabilities of a TMC ETR */
static int tmc_etr_setup_caps(struct device *parent, u32 devid, void *dev_caps)
static int tmc_etr_setup_caps(struct device *parent, u32 devid,
struct csdev_access *access)
{
int rc;
u32 dma_mask = 0;
u32 tmc_pid, dma_mask = 0;
struct tmc_drvdata *drvdata = dev_get_drvdata(parent);
void *dev_caps;
if (!tmc_etr_has_non_secure_access(drvdata))
return -EACCES;
tmc_pid = coresight_get_pid(access);
dev_caps = coresight_get_uci_data_from_amba(tmc_ids, tmc_pid);
/* Set the unadvertised capabilities */
tmc_etr_init_caps(drvdata, (u32)(unsigned long)dev_caps);
@ -437,24 +472,17 @@ static u32 tmc_etr_get_max_burst_size(struct device *dev)
return burst_size;
}
static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
static int __tmc_probe(struct device *dev, struct resource *res)
{
int ret = 0;
u32 devid;
void __iomem *base;
struct device *dev = &adev->dev;
struct coresight_platform_data *pdata = NULL;
struct tmc_drvdata *drvdata;
struct resource *res = &adev->res;
struct tmc_drvdata *drvdata = dev_get_drvdata(dev);
struct coresight_desc desc = { 0 };
struct coresight_dev_list *dev_list = NULL;
ret = -ENOMEM;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata)
goto out;
dev_set_drvdata(dev, drvdata);
/* Validity for the resource is already checked by the AMBA core */
base = devm_ioremap_resource(dev, res);
@ -497,8 +525,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
desc.type = CORESIGHT_DEV_TYPE_SINK;
desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_SYSMEM;
desc.ops = &tmc_etr_cs_ops;
ret = tmc_etr_setup_caps(dev, devid,
coresight_get_uci_data(id));
ret = tmc_etr_setup_caps(dev, devid, &desc.access);
if (ret)
goto out;
idr_init(&drvdata->idr);
@ -530,7 +557,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
ret = PTR_ERR(pdata);
goto out;
}
adev->dev.platform_data = pdata;
dev->platform_data = pdata;
desc.pdata = pdata;
drvdata->csdev = coresight_register(&desc);
@ -545,12 +572,27 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
ret = misc_register(&drvdata->miscdev);
if (ret)
coresight_unregister(drvdata->csdev);
else
pm_runtime_put(&adev->dev);
out:
return ret;
}
static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
{
struct tmc_drvdata *drvdata;
int ret;
drvdata = devm_kzalloc(&adev->dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata)
return -ENOMEM;
amba_set_drvdata(adev, drvdata);
ret = __tmc_probe(&adev->dev, &adev->res);
if (!ret)
pm_runtime_put(&adev->dev);
return ret;
}
static void tmc_shutdown(struct amba_device *adev)
{
unsigned long flags;
@ -573,9 +615,9 @@ out:
spin_unlock_irqrestore(&drvdata->spinlock, flags);
}
static void tmc_remove(struct amba_device *adev)
static void __tmc_remove(struct device *dev)
{
struct tmc_drvdata *drvdata = dev_get_drvdata(&adev->dev);
struct tmc_drvdata *drvdata = dev_get_drvdata(dev);
/*
* Since misc_open() holds a refcount on the f_ops, which is
@ -586,6 +628,11 @@ static void tmc_remove(struct amba_device *adev)
coresight_unregister(drvdata->csdev);
}
static void tmc_remove(struct amba_device *adev)
{
__tmc_remove(&adev->dev);
}
static const struct amba_id tmc_ids[] = {
CS_AMBA_ID(0x000bb961),
/* Coresight SoC 600 TMC-ETR/ETS */
@ -611,7 +658,101 @@ static struct amba_driver tmc_driver = {
.id_table = tmc_ids,
};
module_amba_driver(tmc_driver);
static int tmc_platform_probe(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct tmc_drvdata *drvdata;
int ret = 0;
drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata)
return -ENOMEM;
drvdata->pclk = coresight_get_enable_apb_pclk(&pdev->dev);
if (IS_ERR(drvdata->pclk))
return -ENODEV;
dev_set_drvdata(&pdev->dev, drvdata);
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
ret = __tmc_probe(&pdev->dev, res);
pm_runtime_put(&pdev->dev);
if (ret)
pm_runtime_disable(&pdev->dev);
return ret;
}
static void tmc_platform_remove(struct platform_device *pdev)
{
struct tmc_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
if (WARN_ON(!drvdata))
return;
__tmc_remove(&pdev->dev);
pm_runtime_disable(&pdev->dev);
if (!IS_ERR_OR_NULL(drvdata->pclk))
clk_put(drvdata->pclk);
}
#ifdef CONFIG_PM
static int tmc_runtime_suspend(struct device *dev)
{
struct tmc_drvdata *drvdata = dev_get_drvdata(dev);
if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
clk_disable_unprepare(drvdata->pclk);
return 0;
}
static int tmc_runtime_resume(struct device *dev)
{
struct tmc_drvdata *drvdata = dev_get_drvdata(dev);
if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
clk_prepare_enable(drvdata->pclk);
return 0;
}
#endif
static const struct dev_pm_ops tmc_dev_pm_ops = {
SET_RUNTIME_PM_OPS(tmc_runtime_suspend, tmc_runtime_resume, NULL)
};
#ifdef CONFIG_ACPI
static const struct acpi_device_id tmc_acpi_ids[] = {
{"ARMHC501", 0, 0, 0}, /* ARM CoreSight ETR */
{"ARMHC97C", 0, 0, 0}, /* ARM CoreSight SoC-400 TMC, SoC-600 ETF/ETB */
{},
};
MODULE_DEVICE_TABLE(acpi, tmc_acpi_ids);
#endif
static struct platform_driver tmc_platform_driver = {
.probe = tmc_platform_probe,
.remove_new = tmc_platform_remove,
.driver = {
.name = "coresight-tmc-platform",
.acpi_match_table = ACPI_PTR(tmc_acpi_ids),
.suppress_bind_attrs = true,
.pm = &tmc_dev_pm_ops,
},
};
static int __init tmc_init(void)
{
return coresight_init_driver("tmc", &tmc_driver, &tmc_platform_driver);
}
static void __exit tmc_exit(void)
{
coresight_remove_driver(&tmc_driver, &tmc_platform_driver);
}
module_init(tmc_init);
module_exit(tmc_exit);
MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
MODULE_DESCRIPTION("Arm CoreSight Trace Memory Controller driver");

View File

@ -166,6 +166,7 @@ struct etr_buf {
/**
* struct tmc_drvdata - specifics associated to an TMC component
* @pclk: APB clock if present, otherwise NULL
* @base: memory mapped base address for this component.
* @csdev: component vitals needed by the framework.
* @miscdev: specifics to handle "/dev/xyz.tmc" entry.
@ -189,6 +190,7 @@ struct etr_buf {
* @perf_buf: PERF buffer for ETR.
*/
struct tmc_drvdata {
struct clk *pclk;
void __iomem *base;
struct coresight_device *csdev;
struct miscdevice miscdev;

View File

@ -5,17 +5,19 @@
* Description: CoreSight Trace Port Interface Unit driver
*/
#include <linux/atomic.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <linux/coresight.h>
#include <linux/acpi.h>
#include <linux/amba/bus.h>
#include <linux/atomic.h>
#include <linux/clk.h>
#include <linux/coresight.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include "coresight-priv.h"
@ -52,11 +54,13 @@ DEFINE_CORESIGHT_DEVLIST(tpiu_devs, "tpiu");
/*
* @base: memory mapped base address for this component.
* @atclk: optional clock for the core parts of the TPIU.
* @pclk: APB clock if present, otherwise NULL
* @csdev: component vitals needed by the framework.
*/
struct tpiu_drvdata {
void __iomem *base;
struct clk *atclk;
struct clk *pclk;
struct coresight_device *csdev;
spinlock_t spinlock;
};
@ -122,14 +126,12 @@ static const struct coresight_ops tpiu_cs_ops = {
.sink_ops = &tpiu_sink_ops,
};
static int tpiu_probe(struct amba_device *adev, const struct amba_id *id)
static int __tpiu_probe(struct device *dev, struct resource *res)
{
int ret;
void __iomem *base;
struct device *dev = &adev->dev;
struct coresight_platform_data *pdata = NULL;
struct tpiu_drvdata *drvdata;
struct resource *res = &adev->res;
struct coresight_desc desc = { 0 };
desc.name = coresight_alloc_device_name(&tpiu_devs, dev);
@ -142,12 +144,16 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id)
spin_lock_init(&drvdata->spinlock);
drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */
drvdata->atclk = devm_clk_get(dev, "atclk"); /* optional */
if (!IS_ERR(drvdata->atclk)) {
ret = clk_prepare_enable(drvdata->atclk);
if (ret)
return ret;
}
drvdata->pclk = coresight_get_enable_apb_pclk(dev);
if (IS_ERR(drvdata->pclk))
return -ENODEV;
dev_set_drvdata(dev, drvdata);
/* Validity for the resource is already checked by the AMBA core */
@ -173,21 +179,34 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id)
desc.dev = dev;
drvdata->csdev = coresight_register(&desc);
if (!IS_ERR(drvdata->csdev)) {
pm_runtime_put(&adev->dev);
if (!IS_ERR(drvdata->csdev))
return 0;
}
return PTR_ERR(drvdata->csdev);
}
static void tpiu_remove(struct amba_device *adev)
static int tpiu_probe(struct amba_device *adev, const struct amba_id *id)
{
struct tpiu_drvdata *drvdata = dev_get_drvdata(&adev->dev);
int ret;
ret = __tpiu_probe(&adev->dev, &adev->res);
if (!ret)
pm_runtime_put(&adev->dev);
return ret;
}
static void __tpiu_remove(struct device *dev)
{
struct tpiu_drvdata *drvdata = dev_get_drvdata(dev);
coresight_unregister(drvdata->csdev);
}
static void tpiu_remove(struct amba_device *adev)
{
__tpiu_remove(&adev->dev);
}
#ifdef CONFIG_PM
static int tpiu_runtime_suspend(struct device *dev)
{
@ -196,6 +215,8 @@ static int tpiu_runtime_suspend(struct device *dev)
if (drvdata && !IS_ERR(drvdata->atclk))
clk_disable_unprepare(drvdata->atclk);
if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
clk_disable_unprepare(drvdata->pclk);
return 0;
}
@ -206,6 +227,8 @@ static int tpiu_runtime_resume(struct device *dev)
if (drvdata && !IS_ERR(drvdata->atclk))
clk_prepare_enable(drvdata->atclk);
if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
clk_prepare_enable(drvdata->pclk);
return 0;
}
#endif
@ -245,7 +268,66 @@ static struct amba_driver tpiu_driver = {
.id_table = tpiu_ids,
};
module_amba_driver(tpiu_driver);
static int tpiu_platform_probe(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
int ret;
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
ret = __tpiu_probe(&pdev->dev, res);
pm_runtime_put(&pdev->dev);
if (ret)
pm_runtime_disable(&pdev->dev);
return ret;
}
static void tpiu_platform_remove(struct platform_device *pdev)
{
struct tpiu_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
if (WARN_ON(!drvdata))
return;
__tpiu_remove(&pdev->dev);
pm_runtime_disable(&pdev->dev);
if (!IS_ERR_OR_NULL(drvdata->pclk))
clk_put(drvdata->pclk);
}
#ifdef CONFIG_ACPI
static const struct acpi_device_id tpiu_acpi_ids[] = {
{"ARMHC979", 0, 0, 0}, /* ARM CoreSight TPIU */
{}
};
MODULE_DEVICE_TABLE(acpi, tpiu_acpi_ids);
#endif
static struct platform_driver tpiu_platform_driver = {
.probe = tpiu_platform_probe,
.remove_new = tpiu_platform_remove,
.driver = {
.name = "coresight-tpiu-platform",
.acpi_match_table = ACPI_PTR(tpiu_acpi_ids),
.suppress_bind_attrs = true,
.pm = &tpiu_dev_pm_ops,
},
};
static int __init tpiu_init(void)
{
return coresight_init_driver("tpiu", &tpiu_driver, &tpiu_platform_driver);
}
static void __exit tpiu_exit(void)
{
coresight_remove_driver(&tpiu_driver, &tpiu_platform_driver);
}
module_init(tpiu_init);
module_exit(tpiu_exit);
MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");

View File

@ -1221,6 +1221,7 @@ static int hisi_ptt_register_pmu(struct hisi_ptt *hisi_ptt)
hisi_ptt->hisi_ptt_pmu = (struct pmu) {
.module = THIS_MODULE,
.parent = &hisi_ptt->pdev->dev,
.capabilities = PERF_PMU_CAP_EXCLUSIVE | PERF_PMU_CAP_NO_EXCLUDE,
.task_ctx_nr = perf_sw_context,
.attr_groups = hisi_ptt_pmu_groups,

View File

@ -12,6 +12,7 @@
#include <linux/io.h>
#include <linux/perf_event.h>
#include <linux/sched.h>
#include <linux/platform_device.h>
/* Peripheral id registers (0xFD0-0xFEC) */
#define CORESIGHT_PERIPHIDR4 0xfd0
@ -658,4 +659,9 @@ coresight_find_output_type(struct coresight_platform_data *pdata,
enum coresight_dev_type type,
union coresight_dev_subtype subtype);
int coresight_init_driver(const char *drv, struct amba_driver *amba_drv,
struct platform_driver *pdev_drv);
void coresight_remove_driver(struct amba_driver *amba_drv,
struct platform_driver *pdev_drv);
#endif /* _LINUX_COREISGHT_H */