coresigh: Updates for v6.6

Coresight and hwtracing subsystem updates for Linux v6.6 includes:
 
  - ACPI support for CoreSight ETMv4x via system instructions and Arm ETE (v9.x).
  - Fix potential sleeping in atomic context for TRBE driver
  - Fix memory leak in ACPI platform parsing code
  - Fix all warnings with W=1
  - Fix warning with double free attempt for TRBE platform data
  - Miscellaneous cleanups and fixes
 
  Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEuFy0byloRoXZHaWBxcXRZPKyBqEFAmTfqWAACgkQxcXRZPKy
 BqFxfA//VIzBiM/Az6Zr00ER93MVdWPRJcCOo6VDO3gZSz7bpzHMdUMaohDmNvhy
 DYWYxmhD8XMzR++SX9gF51CasjziRfOTFNFk8aUIZZiQ/aUCtofUh2SCTZJArnJw
 igNKJmQIZuYb361k4ctrp01wLScAPjx3crwCJTZqJ1uOxgItksYKxPeWf05W9RPM
 DD2GWvkRr6sctaW/2P+46SNhT9+QOlA7F2k+qhoCYWIt99yewoBXIBxJA6+37xG2
 H2fB8/y4fws5XMFUQ7tlld0vRuLoVSD3uPLGXDl8Owpwrh7C5Ea5jue0tMFtpcr2
 IqtbBBJ9CZjEEvQuI8WduvHDkvU6Jlod8O7bX7Fx0Pn6EPBQJVk83sxo0a6VMaGI
 IWkxaG4oa6zUSKHaR6a9o/RxLRobJ/yLmKt6DsT+Zf8bv4BhZhm2lcTz8N9Ei9sl
 a5oGMF/TQymZXvR6GqawZKcvxazGTwA4r1EcBB2WG+gtu5jPBQAb80qGO7EyxaOl
 a75U0WZqkT+EX9K36xUPzxFQn+ncYbwO08uPYfRRQa5QYiA90aZ/6/Lea6HBGhw9
 FBALYeM3sxV5qSs5GvcnGJuJWD9pRijNNi0NtqzSSn1Jne8DmSKB4/98gkKibljT
 BrtjWj7vvMNo0IuVHdzsBqZ8H9WL09hajixkCVCbX2/u+01ZrF4=
 =KHsb
 -----END PGP SIGNATURE-----

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

Suzuki writes:

coresigh: Updates for v6.6

Coresight and hwtracing subsystem updates for Linux v6.6 includes:

 - ACPI support for CoreSight ETMv4x via system instructions and Arm ETE (v9.x).
 - Fix potential sleeping in atomic context for TRBE driver
 - Fix memory leak in ACPI platform parsing code
 - Fix all warnings with W=1
 - Fix warning with double free attempt for TRBE platform data
 - Miscellaneous cleanups and fixes

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

* tag 'coresight-next-v6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/coresight/linux:
  coresight: trbe: Fix TRBE potential sleep in atomic context
  coresight: Fix memory leak in acpi_buffer->pointer
  coresight: etm4x: Ensure valid drvdata and clock before clk_put()
  coresight: trbe: Allocate platform data per device
  hwtracing: hisi_ptt: Use pci_dev_id() to simplify the code
  coresight: dummy: simplify the code with module_platform_driver
  coresight: tmc: Explicit type conversions to prevent integer overflow
  coresight: trbe: Directly use ID_AA64DFR0_EL1_TraceBuffer_IMP
  coresight: Fix all W=1 build warnings
  coresight: etm4x: Add ACPI support in platform driver
  coresight: platform: acpi: Ignore the absence of graph
  coresight: etm4x: Change etm4_platform_driver driver for MMIO devices
  coresight: etm4x: Drop pid argument from etm4_probe()
  coresight: etm4x: Drop iomem 'base' argument from etm4_probe()
  coresight: etm4x: Allocate and device assign 'struct etmv4_drvdata' earlier
  hwtracing: coresight: Explicitly include correct DT includes
This commit is contained in:
Greg Kroah-Hartman 2023-08-22 15:54:52 +02:00
commit 5bb5117b14
15 changed files with 225 additions and 85 deletions

View File

@ -22,7 +22,6 @@
static const struct acpi_device_id amba_id_list[] = {
{"ARMH0061", 0}, /* PL061 GPIO Device */
{"ARMH0330", 0}, /* ARM DMA Controller DMA-330 */
{"ARMHC500", 0}, /* ARM CoreSight ETM4x */
{"ARMHC501", 0}, /* ARM CoreSight ETR */
{"ARMHC502", 0}, /* ARM CoreSight STM */
{"ARMHC503", 0}, /* ARM CoreSight Debug */

View File

@ -17,7 +17,7 @@
#include <linux/mutex.h>
#include <linux/clk.h>
#include <linux/coresight.h>
#include <linux/of_platform.h>
#include <linux/property.h>
#include <linux/delay.h>
#include <linux/pm_runtime.h>

View File

@ -22,7 +22,7 @@
#include "coresight-priv.h"
#include "coresight-cti.h"
/**
/*
* CTI devices can be associated with a PE, or be connected to CoreSight
* hardware. We have a list of all CTIs irrespective of CPU bound or
* otherwise.

View File

@ -147,17 +147,7 @@ static struct platform_driver dummy_driver = {
},
};
static int __init dummy_init(void)
{
return platform_driver_register(&dummy_driver);
}
module_init(dummy_init);
static void __exit dummy_exit(void)
{
platform_driver_unregister(&dummy_driver);
}
module_exit(dummy_exit);
module_platform_driver(dummy_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("CoreSight dummy driver");

View File

@ -40,7 +40,7 @@
* Invalid offsets will result in fail code return and feature load failure.
*
* @drvdata: driver data to map into.
* @reg: register to map.
* @reg_csdev: register to map.
* @offset: device offset for the register
*/
static int etm4_cfg_map_reg_offset(struct etmv4_drvdata *drvdata,
@ -132,7 +132,7 @@ static int etm4_cfg_map_reg_offset(struct etmv4_drvdata *drvdata,
* etm4_cfg_load_feature - load a feature into a device instance.
*
* @csdev: An ETMv4 CoreSight device.
* @feat: The feature to be loaded.
* @feat_csdev: The feature to be loaded.
*
* The function will load a feature instance into the device, checking that
* the register definitions are valid for the device.

View File

@ -3,6 +3,7 @@
* Copyright (c) 2014, The Linux Foundation. All rights reserved.
*/
#include <linux/acpi.h>
#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/moduleparam.h>
@ -30,6 +31,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
#include <linux/clk/clk-conf.h>
#include <asm/barrier.h>
#include <asm/sections.h>
@ -66,7 +68,6 @@ static u64 etm4_get_access_type(struct etmv4_config *config);
static enum cpuhp_state hp_online;
struct etm4_init_arg {
unsigned int pid;
struct device *dev;
struct csdev_access *csa;
};
@ -370,9 +371,17 @@ static void etm4_disable_arch_specific(struct etmv4_drvdata *drvdata)
}
static void etm4_check_arch_features(struct etmv4_drvdata *drvdata,
unsigned int id)
struct csdev_access *csa)
{
if (etm4_hisi_match_pid(id))
/*
* TRCPIDR* registers are not required for ETMs with system
* instructions. They must be identified by the MIDR+REVIDRs.
* Skip the TRCPID checks for now.
*/
if (!csa->io_mem)
return;
if (etm4_hisi_match_pid(coresight_get_pid(csa)))
set_bit(ETM4_IMPDEF_HISI_CORE_COMMIT, drvdata->arch_features);
}
#else
@ -385,7 +394,7 @@ static void etm4_disable_arch_specific(struct etmv4_drvdata *drvdata)
}
static void etm4_check_arch_features(struct etmv4_drvdata *drvdata,
unsigned int id)
struct csdev_access *csa)
{
}
#endif /* CONFIG_ETM4X_IMPDEF_FEATURE */
@ -1066,11 +1075,21 @@ static bool etm4_init_sysreg_access(struct etmv4_drvdata *drvdata,
return true;
}
static bool is_devtype_cpu_trace(void __iomem *base)
{
u32 devtype = readl(base + TRCDEVTYPE);
return (devtype == CS_DEVTYPE_PE_TRACE);
}
static bool etm4_init_iomem_access(struct etmv4_drvdata *drvdata,
struct csdev_access *csa)
{
u32 devarch = readl_relaxed(drvdata->base + TRCDEVARCH);
if (!is_coresight_device(drvdata->base) || !is_devtype_cpu_trace(drvdata->base))
return false;
/*
* All ETMs must implement TRCDEVARCH to indicate that
* the component is an ETMv4. Even though TRCIDR1 also
@ -1161,7 +1180,7 @@ static void etm4_init_arch_data(void *info)
etm4_os_unlock_csa(drvdata, csa);
etm4_cs_unlock(drvdata, csa);
etm4_check_arch_features(drvdata, init_arg->pid);
etm4_check_arch_features(drvdata, csa);
/* find all capabilities of the tracing unit */
etmidr0 = etm4x_relaxed_read32(csa, TRCIDR0);
@ -2044,19 +2063,16 @@ static int etm4_add_coresight_dev(struct etm4_init_arg *init_arg)
return 0;
}
static int etm4_probe(struct device *dev, void __iomem *base, u32 etm_pid)
static int etm4_probe(struct device *dev)
{
struct etmv4_drvdata *drvdata;
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
struct csdev_access access = { 0 };
struct etm4_init_arg init_arg = { 0 };
struct etm4_init_arg *delayed;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata)
if (WARN_ON(!drvdata))
return -ENOMEM;
dev_set_drvdata(dev, drvdata);
if (pm_save_enable == PARAM_PM_SAVE_FIRMWARE)
pm_save_enable = coresight_loses_context_with_cpu(dev) ?
PARAM_PM_SAVE_SELF_HOSTED : PARAM_PM_SAVE_NEVER;
@ -2068,8 +2084,6 @@ static int etm4_probe(struct device *dev, void __iomem *base, u32 etm_pid)
return -ENOMEM;
}
drvdata->base = base;
spin_lock_init(&drvdata->spinlock);
drvdata->cpu = coresight_get_cpu(dev);
@ -2078,7 +2092,6 @@ static int etm4_probe(struct device *dev, void __iomem *base, u32 etm_pid)
init_arg.dev = dev;
init_arg.csa = &access;
init_arg.pid = etm_pid;
/*
* Serialize against CPUHP callbacks to avoid race condition
@ -2108,6 +2121,7 @@ static int etm4_probe(struct device *dev, void __iomem *base, u32 etm_pid)
static int etm4_probe_amba(struct amba_device *adev, const struct amba_id *id)
{
struct etmv4_drvdata *drvdata;
void __iomem *base;
struct device *dev = &adev->dev;
struct resource *res = &adev->res;
@ -2118,7 +2132,13 @@ static int etm4_probe_amba(struct amba_device *adev, const struct amba_id *id)
if (IS_ERR(base))
return PTR_ERR(base);
ret = etm4_probe(dev, base, id->id);
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata)
return -ENOMEM;
drvdata->base = base;
dev_set_drvdata(dev, drvdata);
ret = etm4_probe(dev);
if (!ret)
pm_runtime_put(&adev->dev);
@ -2127,18 +2147,32 @@ static int etm4_probe_amba(struct amba_device *adev, const struct amba_id *id)
static int etm4_probe_platform_dev(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
struct etmv4_drvdata *drvdata;
int ret;
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;
if (res) {
drvdata->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(drvdata->base)) {
clk_put(drvdata->pclk);
return PTR_ERR(drvdata->base);
}
}
dev_set_drvdata(&pdev->dev, drvdata);
pm_runtime_get_noresume(&pdev->dev);
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
/*
* System register based devices could match the
* HW by reading appropriate registers on the HW
* and thus we could skip the PID.
*/
ret = etm4_probe(&pdev->dev, NULL, 0);
ret = etm4_probe(&pdev->dev);
pm_runtime_put(&pdev->dev);
return ret;
@ -2178,7 +2212,7 @@ static struct amba_cs_uci_id uci_id_etm4[] = {
/* ETMv4 UCI data */
.devarch = ETM_DEVARCH_ETMv4x_ARCH,
.devarch_mask = ETM_DEVARCH_ID_MASK,
.devtype = 0x00000013,
.devtype = CS_DEVTYPE_PE_TRACE,
}
};
@ -2234,6 +2268,10 @@ static int __exit etm4_remove_platform_dev(struct platform_device *pdev)
if (drvdata)
etm4_remove_dev(drvdata);
pm_runtime_disable(&pdev->dev);
if (drvdata && !IS_ERR_OR_NULL(drvdata->pclk))
clk_put(drvdata->pclk);
return 0;
}
@ -2278,19 +2316,55 @@ static struct amba_driver etm4x_amba_driver = {
.id_table = etm4_ids,
};
#ifdef CONFIG_PM
static int etm4_runtime_suspend(struct device *dev)
{
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
if (drvdata->pclk && !IS_ERR(drvdata->pclk))
clk_disable_unprepare(drvdata->pclk);
return 0;
}
static int etm4_runtime_resume(struct device *dev)
{
struct etmv4_drvdata *drvdata = dev_get_drvdata(dev);
if (drvdata->pclk && !IS_ERR(drvdata->pclk))
clk_prepare_enable(drvdata->pclk);
return 0;
}
#endif
static const struct dev_pm_ops etm4_dev_pm_ops = {
SET_RUNTIME_PM_OPS(etm4_runtime_suspend, etm4_runtime_resume, NULL)
};
static const struct of_device_id etm4_sysreg_match[] = {
{ .compatible = "arm,coresight-etm4x-sysreg" },
{ .compatible = "arm,embedded-trace-extension" },
{}
};
#ifdef CONFIG_ACPI
static const struct acpi_device_id etm4x_acpi_ids[] = {
{"ARMHC500", 0}, /* ARM CoreSight ETM4x */
{}
};
MODULE_DEVICE_TABLE(acpi, etm4x_acpi_ids);
#endif
static struct platform_driver etm4_platform_driver = {
.probe = etm4_probe_platform_dev,
.remove = etm4_remove_platform_dev,
.driver = {
.name = "coresight-etm4x",
.of_match_table = etm4_sysreg_match,
.acpi_match_table = ACPI_PTR(etm4x_acpi_ids),
.suppress_bind_attrs = true,
.pm = &etm4_dev_pm_ops,
},
};

View File

@ -701,6 +701,8 @@
#define ETM_DEVARCH_ETE_ARCH \
(ETM_DEVARCH_ARCHITECT_ARM | ETM_DEVARCH_ARCHID_ETE | ETM_DEVARCH_PRESENT)
#define CS_DEVTYPE_PE_TRACE 0x00000013
#define TRCSTATR_IDLE_BIT 0
#define TRCSTATR_PMSTABLE_BIT 1
#define ETM_DEFAULT_ADDR_COMP 0
@ -944,6 +946,7 @@ struct etmv4_save_state {
/**
* struct etm4_drvdata - specifics associated to an ETM component
* @pclk APB clock if present, otherwise NULL
* @base: Memory mapped base address for this component.
* @csdev: Component vitals needed by the framework.
* @spinlock: Only one at a time pls.
@ -1009,6 +1012,7 @@ struct etmv4_save_state {
* @arch_features: Bitmap of arch features of etmv4 devices.
*/
struct etmv4_drvdata {
struct clk *pclk;
void __iomem *base;
struct coresight_device *csdev;
spinlock_t spinlock;

View File

@ -9,9 +9,7 @@
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_graph.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/amba/bus.h>
#include <linux/coresight.h>
@ -494,19 +492,18 @@ static inline bool acpi_validate_dsd_graph(const union acpi_object *graph)
/* acpi_get_dsd_graph - Find the _DSD Graph property for the given device. */
static const union acpi_object *
acpi_get_dsd_graph(struct acpi_device *adev)
acpi_get_dsd_graph(struct acpi_device *adev, struct acpi_buffer *buf)
{
int i;
struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
acpi_status status;
const union acpi_object *dsd;
status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL,
&buf, ACPI_TYPE_PACKAGE);
buf, ACPI_TYPE_PACKAGE);
if (ACPI_FAILURE(status))
return NULL;
dsd = buf.pointer;
dsd = buf->pointer;
/*
* _DSD property consists tuples { Prop_UUID, Package() }
@ -557,12 +554,12 @@ acpi_validate_coresight_graph(const union acpi_object *cs_graph)
* returns NULL.
*/
static const union acpi_object *
acpi_get_coresight_graph(struct acpi_device *adev)
acpi_get_coresight_graph(struct acpi_device *adev, struct acpi_buffer *buf)
{
const union acpi_object *graph_list, *graph;
int i, nr_graphs;
graph_list = acpi_get_dsd_graph(adev);
graph_list = acpi_get_dsd_graph(adev, buf);
if (!graph_list)
return graph_list;
@ -663,18 +660,24 @@ static int acpi_coresight_parse_graph(struct device *dev,
struct acpi_device *adev,
struct coresight_platform_data *pdata)
{
int ret = 0;
int i, nlinks;
const union acpi_object *graph;
struct coresight_connection conn, zero_conn = {};
struct coresight_connection *new_conn;
struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
graph = acpi_get_coresight_graph(adev);
graph = acpi_get_coresight_graph(adev, &buf);
/*
* There are no graph connections, which is fine for some components.
* e.g., ETE
*/
if (!graph)
return -ENOENT;
goto free;
nlinks = graph->package.elements[2].integer.value;
if (!nlinks)
return 0;
goto free;
for (i = 0; i < nlinks; i++) {
const union acpi_object *link = &graph->package.elements[3 + i];
@ -682,17 +685,28 @@ static int acpi_coresight_parse_graph(struct device *dev,
conn = zero_conn;
dir = acpi_coresight_parse_link(adev, link, &conn);
if (dir < 0)
return dir;
if (dir < 0) {
ret = dir;
goto free;
}
if (dir == ACPI_CORESIGHT_LINK_MASTER) {
new_conn = coresight_add_out_conn(dev, pdata, &conn);
if (IS_ERR(new_conn))
return PTR_ERR(new_conn);
if (IS_ERR(new_conn)) {
ret = PTR_ERR(new_conn);
goto free;
}
}
}
return 0;
free:
/*
* When ACPI fails to alloc a buffer, it will free the buffer
* created via ACPI_ALLOCATE_BUFFER and set to NULL.
* ACPI_FREE can handle NULL pointers, so free it directly.
*/
ACPI_FREE(buf.pointer);
return ret;
}
/*

View File

@ -452,7 +452,7 @@ static int tmc_set_etf_buffer(struct coresight_device *csdev,
return -EINVAL;
/* wrap head around to the amount of space we have */
head = handle->head & ((buf->nr_pages << PAGE_SHIFT) - 1);
head = handle->head & (((unsigned long)buf->nr_pages << PAGE_SHIFT) - 1);
/* find the page to write to */
buf->cur = head / PAGE_SIZE;

View File

@ -45,7 +45,8 @@ struct etr_perf_buffer {
};
/* Convert the perf index to an offset within the ETR buffer */
#define PERF_IDX2OFF(idx, buf) ((idx) % ((buf)->nr_pages << PAGE_SHIFT))
#define PERF_IDX2OFF(idx, buf) \
((idx) % ((unsigned long)(buf)->nr_pages << PAGE_SHIFT))
/* Lower limit for ETR hardware buffer */
#define TMC_ETR_PERF_MIN_BUF_SIZE SZ_1M
@ -1267,7 +1268,7 @@ alloc_etr_buf(struct tmc_drvdata *drvdata, struct perf_event *event,
* than the size requested via sysfs.
*/
if ((nr_pages << PAGE_SHIFT) > drvdata->size) {
etr_buf = tmc_alloc_etr_buf(drvdata, (nr_pages << PAGE_SHIFT),
etr_buf = tmc_alloc_etr_buf(drvdata, ((ssize_t)nr_pages << PAGE_SHIFT),
0, node, NULL);
if (!IS_ERR(etr_buf))
goto done;

View File

@ -325,7 +325,7 @@ ssize_t tmc_sg_table_get_data(struct tmc_sg_table *sg_table,
static inline unsigned long
tmc_sg_table_buf_size(struct tmc_sg_table *sg_table)
{
return sg_table->data_pages.nr_pages << PAGE_SHIFT;
return (unsigned long)sg_table->data_pages.nr_pages << PAGE_SHIFT;
}
struct coresight_device *tmc_etr_get_catu_device(struct tmc_drvdata *drvdata);

View File

@ -1225,6 +1225,16 @@ static void arm_trbe_enable_cpu(void *info)
enable_percpu_irq(drvdata->irq, IRQ_TYPE_NONE);
}
static void arm_trbe_disable_cpu(void *info)
{
struct trbe_drvdata *drvdata = info;
struct trbe_cpudata *cpudata = this_cpu_ptr(drvdata->cpudata);
disable_percpu_irq(drvdata->irq);
trbe_reset_local(cpudata);
}
static void arm_trbe_register_coresight_cpu(struct trbe_drvdata *drvdata, int cpu)
{
struct trbe_cpudata *cpudata = per_cpu_ptr(drvdata->cpudata, cpu);
@ -1244,10 +1254,13 @@ static void arm_trbe_register_coresight_cpu(struct trbe_drvdata *drvdata, int cp
if (!desc.name)
goto cpu_clear;
desc.pdata = coresight_get_platform_data(dev);
if (IS_ERR(desc.pdata))
goto cpu_clear;
desc.type = CORESIGHT_DEV_TYPE_SINK;
desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_PERCPU_SYSMEM;
desc.ops = &arm_trbe_cs_ops;
desc.pdata = dev_get_platdata(dev);
desc.groups = arm_trbe_groups;
desc.dev = dev;
trbe_csdev = coresight_register(&desc);
@ -1326,18 +1339,12 @@ cpu_clear:
cpumask_clear_cpu(cpu, &drvdata->supported_cpus);
}
static void arm_trbe_remove_coresight_cpu(void *info)
static void arm_trbe_remove_coresight_cpu(struct trbe_drvdata *drvdata, int cpu)
{
int cpu = smp_processor_id();
struct trbe_drvdata *drvdata = info;
struct trbe_cpudata *cpudata = per_cpu_ptr(drvdata->cpudata, cpu);
struct coresight_device *trbe_csdev = coresight_get_percpu_sink(cpu);
disable_percpu_irq(drvdata->irq);
trbe_reset_local(cpudata);
if (trbe_csdev) {
coresight_unregister(trbe_csdev);
cpudata->drvdata = NULL;
coresight_set_percpu_sink(cpu, NULL);
}
}
@ -1366,8 +1373,10 @@ static int arm_trbe_remove_coresight(struct trbe_drvdata *drvdata)
{
int cpu;
for_each_cpu(cpu, &drvdata->supported_cpus)
smp_call_function_single(cpu, arm_trbe_remove_coresight_cpu, drvdata, 1);
for_each_cpu(cpu, &drvdata->supported_cpus) {
smp_call_function_single(cpu, arm_trbe_disable_cpu, drvdata, 1);
arm_trbe_remove_coresight_cpu(drvdata, cpu);
}
free_percpu(drvdata->cpudata);
return 0;
}
@ -1406,12 +1415,8 @@ static int arm_trbe_cpu_teardown(unsigned int cpu, struct hlist_node *node)
{
struct trbe_drvdata *drvdata = hlist_entry_safe(node, struct trbe_drvdata, hotplug_node);
if (cpumask_test_cpu(cpu, &drvdata->supported_cpus)) {
struct trbe_cpudata *cpudata = per_cpu_ptr(drvdata->cpudata, cpu);
disable_percpu_irq(drvdata->irq);
trbe_reset_local(cpudata);
}
if (cpumask_test_cpu(cpu, &drvdata->supported_cpus))
arm_trbe_disable_cpu(drvdata);
return 0;
}
@ -1479,7 +1484,6 @@ static void arm_trbe_remove_irq(struct trbe_drvdata *drvdata)
static int arm_trbe_device_probe(struct platform_device *pdev)
{
struct coresight_platform_data *pdata;
struct trbe_drvdata *drvdata;
struct device *dev = &pdev->dev;
int ret;
@ -1494,12 +1498,7 @@ static int arm_trbe_device_probe(struct platform_device *pdev)
if (!drvdata)
return -ENOMEM;
pdata = coresight_get_platform_data(dev);
if (IS_ERR(pdata))
return PTR_ERR(pdata);
dev_set_drvdata(dev, drvdata);
dev->platform_data = pdata;
drvdata->pdev = pdev;
ret = arm_trbe_probe_irq(pdev, drvdata);
if (ret)

View File

@ -23,7 +23,7 @@ static inline bool is_trbe_available(void)
unsigned int trbe = cpuid_feature_extract_unsigned_field(aa64dfr0,
ID_AA64DFR0_EL1_TraceBuffer_SHIFT);
return trbe >= 0b0001;
return trbe >= ID_AA64DFR0_EL1_TraceBuffer_IMP;
}
static inline bool is_trbe_enabled(void)

View File

@ -618,13 +618,13 @@ static int hisi_ptt_notifier_call(struct notifier_block *nb, unsigned long actio
if (!root_port)
return 0;
port_devid = PCI_DEVID(root_port->bus->number, root_port->devfn);
port_devid = pci_dev_id(root_port);
if (port_devid < hisi_ptt->lower_bdf ||
port_devid > hisi_ptt->upper_bdf)
return 0;
info.is_port = pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT;
info.devid = PCI_DEVID(pdev->bus->number, pdev->devfn);
info.devid = pci_dev_id(pdev);
switch (action) {
case BUS_NOTIFY_ADD_DEVICE:
@ -664,7 +664,7 @@ static int hisi_ptt_init_filters(struct pci_dev *pdev, void *data)
if (!root_port)
return 0;
port_devid = PCI_DEVID(root_port->bus->number, root_port->devfn);
port_devid = pci_dev_id(root_port);
if (port_devid < hisi_ptt->lower_bdf ||
port_devid > hisi_ptt->upper_bdf)
return 0;
@ -674,7 +674,7 @@ static int hisi_ptt_init_filters(struct pci_dev *pdev, void *data)
* should be partial initialized and users would know which filter fails
* through the log. Other functions of PTT device are still available.
*/
filter = hisi_ptt_alloc_add_filter(hisi_ptt, PCI_DEVID(pdev->bus->number, pdev->devfn),
filter = hisi_ptt_alloc_add_filter(hisi_ptt, pci_dev_id(pdev),
pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT);
if (!filter)
return -ENOMEM;

View File

@ -6,6 +6,8 @@
#ifndef _LINUX_CORESIGHT_H
#define _LINUX_CORESIGHT_H
#include <linux/amba/bus.h>
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/perf_event.h>
@ -386,6 +388,63 @@ static inline u32 csdev_access_relaxed_read32(struct csdev_access *csa,
return csa->read(offset, true, false);
}
#define CORESIGHT_CIDRn(i) (0xFF0 + ((i) * 4))
static inline u32 coresight_get_cid(void __iomem *base)
{
u32 i, cid = 0;
for (i = 0; i < 4; i++)
cid |= readl(base + CORESIGHT_CIDRn(i)) << (i * 8);
return cid;
}
static inline bool is_coresight_device(void __iomem *base)
{
u32 cid = coresight_get_cid(base);
return cid == CORESIGHT_CID;
}
/*
* Attempt to find and enable "APB clock" for the given device
*
* Returns:
*
* clk - Clock is found and enabled
* NULL - clock is not found
* ERROR - Clock is found but failed to enable
*/
static inline struct clk *coresight_get_enable_apb_pclk(struct device *dev)
{
struct clk *pclk;
int ret;
pclk = clk_get(dev, "apb_pclk");
if (IS_ERR(pclk))
return NULL;
ret = clk_prepare_enable(pclk);
if (ret) {
clk_put(pclk);
return ERR_PTR(ret);
}
return pclk;
}
#define CORESIGHT_PIDRn(i) (0xFE0 + ((i) * 4))
static inline u32 coresight_get_pid(struct csdev_access *csa)
{
u32 i, pid = 0;
for (i = 0; i < 4; i++)
pid |= csdev_access_relaxed_read32(csa, CORESIGHT_PIDRn(i)) << (i * 8);
return pid;
}
static inline u64 csdev_access_relaxed_read_pair(struct csdev_access *csa,
u32 lo_offset, u32 hi_offset)
{