// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright(C) 2015 Linaro Limited. All rights reserved.
 * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
 */

#include <linux/coresight.h>
#include <linux/coresight-pmu.h>
#include <linux/cpumask.h>
#include <linux/device.h>
#include <linux/list.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/perf_event.h>
#include <linux/percpu-defs.h>
#include <linux/slab.h>
#include <linux/stringhash.h>
#include <linux/types.h>
#include <linux/workqueue.h>

#include "coresight-config.h"
#include "coresight-etm-perf.h"
#include "coresight-priv.h"
#include "coresight-syscfg.h"

static struct pmu etm_pmu;
static bool etm_perf_up;

/*
 * An ETM context for a running event includes the perf aux handle
 * and aux_data. For ETM, the aux_data (etm_event_data), consists of
 * the trace path and the sink configuration. The event data is accessible
 * via perf_get_aux(handle). However, a sink could "end" a perf output
 * handle via the IRQ handler. And if the "sink" encounters a failure
 * to "begin" another session (e.g due to lack of space in the buffer),
 * the handle will be cleared. Thus, the event_data may not be accessible
 * from the handle when we get to the etm_event_stop(), which is required
 * for stopping the trace path. The event_data is guaranteed to stay alive
 * until "free_aux()", which cannot happen as long as the event is active on
 * the ETM. Thus the event_data for the session must be part of the ETM context
 * to make sure we can disable the trace path.
 */
struct etm_ctxt {
	struct perf_output_handle handle;
	struct etm_event_data *event_data;
};

static DEFINE_PER_CPU(struct etm_ctxt, etm_ctxt);
static DEFINE_PER_CPU(struct coresight_device *, csdev_src);

/*
 * The PMU formats were orignally for ETMv3.5/PTM's ETMCR 'config';
 * now take them as general formats and apply on all ETMs.
 */
PMU_FORMAT_ATTR(cycacc,		"config:" __stringify(ETM_OPT_CYCACC));
/* contextid1 enables tracing CONTEXTIDR_EL1 for ETMv4 */
PMU_FORMAT_ATTR(contextid1,	"config:" __stringify(ETM_OPT_CTXTID));
/* contextid2 enables tracing CONTEXTIDR_EL2 for ETMv4 */
PMU_FORMAT_ATTR(contextid2,	"config:" __stringify(ETM_OPT_CTXTID2));
PMU_FORMAT_ATTR(timestamp,	"config:" __stringify(ETM_OPT_TS));
PMU_FORMAT_ATTR(retstack,	"config:" __stringify(ETM_OPT_RETSTK));
/* preset - if sink ID is used as a configuration selector */
PMU_FORMAT_ATTR(preset,		"config:0-3");
/* Sink ID - same for all ETMs */
PMU_FORMAT_ATTR(sinkid,		"config2:0-31");
/* config ID - set if a system configuration is selected */
PMU_FORMAT_ATTR(configid,	"config2:32-63");


/*
 * contextid always traces the "PID".  The PID is in CONTEXTIDR_EL1
 * when the kernel is running at EL1; when the kernel is at EL2,
 * the PID is in CONTEXTIDR_EL2.
 */
static ssize_t format_attr_contextid_show(struct device *dev,
					  struct device_attribute *attr,
					  char *page)
{
	int pid_fmt = ETM_OPT_CTXTID;

#if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X)
	pid_fmt = is_kernel_in_hyp_mode() ? ETM_OPT_CTXTID2 : ETM_OPT_CTXTID;
#endif
	return sprintf(page, "config:%d\n", pid_fmt);
}

struct device_attribute format_attr_contextid =
	__ATTR(contextid, 0444, format_attr_contextid_show, NULL);

static struct attribute *etm_config_formats_attr[] = {
	&format_attr_cycacc.attr,
	&format_attr_contextid.attr,
	&format_attr_contextid1.attr,
	&format_attr_contextid2.attr,
	&format_attr_timestamp.attr,
	&format_attr_retstack.attr,
	&format_attr_sinkid.attr,
	&format_attr_preset.attr,
	&format_attr_configid.attr,
	NULL,
};

static const struct attribute_group etm_pmu_format_group = {
	.name   = "format",
	.attrs  = etm_config_formats_attr,
};

static struct attribute *etm_config_sinks_attr[] = {
	NULL,
};

static const struct attribute_group etm_pmu_sinks_group = {
	.name   = "sinks",
	.attrs  = etm_config_sinks_attr,
};

static struct attribute *etm_config_events_attr[] = {
	NULL,
};

static const struct attribute_group etm_pmu_events_group = {
	.name   = "events",
	.attrs  = etm_config_events_attr,
};

static const struct attribute_group *etm_pmu_attr_groups[] = {
	&etm_pmu_format_group,
	&etm_pmu_sinks_group,
	&etm_pmu_events_group,
	NULL,
};

static inline struct list_head **
etm_event_cpu_path_ptr(struct etm_event_data *data, int cpu)
{
	return per_cpu_ptr(data->path, cpu);
}

static inline struct list_head *
etm_event_cpu_path(struct etm_event_data *data, int cpu)
{
	return *etm_event_cpu_path_ptr(data, cpu);
}

static void etm_event_read(struct perf_event *event) {}

static int etm_addr_filters_alloc(struct perf_event *event)
{
	struct etm_filters *filters;
	int node = event->cpu == -1 ? -1 : cpu_to_node(event->cpu);

	filters = kzalloc_node(sizeof(struct etm_filters), GFP_KERNEL, node);
	if (!filters)
		return -ENOMEM;

	if (event->parent)
		memcpy(filters, event->parent->hw.addr_filters,
		       sizeof(*filters));

	event->hw.addr_filters = filters;

	return 0;
}

static void etm_event_destroy(struct perf_event *event)
{
	kfree(event->hw.addr_filters);
	event->hw.addr_filters = NULL;
}

static int etm_event_init(struct perf_event *event)
{
	int ret = 0;

	if (event->attr.type != etm_pmu.type) {
		ret = -ENOENT;
		goto out;
	}

	ret = etm_addr_filters_alloc(event);
	if (ret)
		goto out;

	event->destroy = etm_event_destroy;
out:
	return ret;
}

static void free_sink_buffer(struct etm_event_data *event_data)
{
	int cpu;
	cpumask_t *mask = &event_data->mask;
	struct coresight_device *sink;

	if (!event_data->snk_config)
		return;

	if (WARN_ON(cpumask_empty(mask)))
		return;

	cpu = cpumask_first(mask);
	sink = coresight_get_sink(etm_event_cpu_path(event_data, cpu));
	sink_ops(sink)->free_buffer(event_data->snk_config);
}

static void free_event_data(struct work_struct *work)
{
	int cpu;
	cpumask_t *mask;
	struct etm_event_data *event_data;

	event_data = container_of(work, struct etm_event_data, work);
	mask = &event_data->mask;

	/* Free the sink buffers, if there are any */
	free_sink_buffer(event_data);

	/* clear any configuration we were using */
	if (event_data->cfg_hash)
		cscfg_deactivate_config(event_data->cfg_hash);

	for_each_cpu(cpu, mask) {
		struct list_head **ppath;

		ppath = etm_event_cpu_path_ptr(event_data, cpu);
		if (!(IS_ERR_OR_NULL(*ppath)))
			coresight_release_path(*ppath);
		*ppath = NULL;
	}

	free_percpu(event_data->path);
	kfree(event_data);
}

static void *alloc_event_data(int cpu)
{
	cpumask_t *mask;
	struct etm_event_data *event_data;

	/* First get memory for the session's data */
	event_data = kzalloc(sizeof(struct etm_event_data), GFP_KERNEL);
	if (!event_data)
		return NULL;


	mask = &event_data->mask;
	if (cpu != -1)
		cpumask_set_cpu(cpu, mask);
	else
		cpumask_copy(mask, cpu_present_mask);

	/*
	 * Each CPU has a single path between source and destination.  As such
	 * allocate an array using CPU numbers as indexes.  That way a path
	 * for any CPU can easily be accessed at any given time.  We proceed
	 * the same way for sessions involving a single CPU.  The cost of
	 * unused memory when dealing with single CPU trace scenarios is small
	 * compared to the cost of searching through an optimized array.
	 */
	event_data->path = alloc_percpu(struct list_head *);

	if (!event_data->path) {
		kfree(event_data);
		return NULL;
	}

	return event_data;
}

static void etm_free_aux(void *data)
{
	struct etm_event_data *event_data = data;

	schedule_work(&event_data->work);
}

/*
 * Check if two given sinks are compatible with each other,
 * so that they can use the same sink buffers, when an event
 * moves around.
 */
static bool sinks_compatible(struct coresight_device *a,
			     struct coresight_device *b)
{
	if (!a || !b)
		return false;
	/*
	 * If the sinks are of the same subtype and driven
	 * by the same driver, we can use the same buffer
	 * on these sinks.
	 */
	return (a->subtype.sink_subtype == b->subtype.sink_subtype) &&
	       (sink_ops(a) == sink_ops(b));
}

static void *etm_setup_aux(struct perf_event *event, void **pages,
			   int nr_pages, bool overwrite)
{
	u32 id, cfg_hash;
	int cpu = event->cpu;
	cpumask_t *mask;
	struct coresight_device *sink = NULL;
	struct coresight_device *user_sink = NULL, *last_sink = NULL;
	struct etm_event_data *event_data = NULL;

	event_data = alloc_event_data(cpu);
	if (!event_data)
		return NULL;
	INIT_WORK(&event_data->work, free_event_data);

	/* First get the selected sink from user space. */
	if (event->attr.config2 & GENMASK_ULL(31, 0)) {
		id = (u32)event->attr.config2;
		sink = user_sink = coresight_get_sink_by_id(id);
	}

	/* check if user wants a coresight configuration selected */
	cfg_hash = (u32)((event->attr.config2 & GENMASK_ULL(63, 32)) >> 32);
	if (cfg_hash) {
		if (cscfg_activate_config(cfg_hash))
			goto err;
		event_data->cfg_hash = cfg_hash;
	}

	mask = &event_data->mask;

	/*
	 * Setup the path for each CPU in a trace session. We try to build
	 * trace path for each CPU in the mask. If we don't find an ETM
	 * for the CPU or fail to build a path, we clear the CPU from the
	 * mask and continue with the rest. If ever we try to trace on those
	 * CPUs, we can handle it and fail the session.
	 */
	for_each_cpu(cpu, mask) {
		struct list_head *path;
		struct coresight_device *csdev;

		csdev = per_cpu(csdev_src, cpu);
		/*
		 * If there is no ETM associated with this CPU clear it from
		 * the mask and continue with the rest. If ever we try to trace
		 * on this CPU, we handle it accordingly.
		 */
		if (!csdev) {
			cpumask_clear_cpu(cpu, mask);
			continue;
		}

		/*
		 * No sink provided - look for a default sink for all the ETMs,
		 * where this event can be scheduled.
		 * We allocate the sink specific buffers only once for this
		 * event. If the ETMs have different default sink devices, we
		 * can only use a single "type" of sink as the event can carry
		 * only one sink specific buffer. Thus we have to make sure
		 * that the sinks are of the same type and driven by the same
		 * driver, as the one we allocate the buffer for. As such
		 * we choose the first sink and check if the remaining ETMs
		 * have a compatible default sink. We don't trace on a CPU
		 * if the sink is not compatible.
		 */
		if (!user_sink) {
			/* Find the default sink for this ETM */
			sink = coresight_find_default_sink(csdev);
			if (!sink) {
				cpumask_clear_cpu(cpu, mask);
				continue;
			}

			/* Check if this sink compatible with the last sink */
			if (last_sink && !sinks_compatible(last_sink, sink)) {
				cpumask_clear_cpu(cpu, mask);
				continue;
			}
			last_sink = sink;
		}

		/*
		 * Building a path doesn't enable it, it simply builds a
		 * list of devices from source to sink that can be
		 * referenced later when the path is actually needed.
		 */
		path = coresight_build_path(csdev, sink);
		if (IS_ERR(path)) {
			cpumask_clear_cpu(cpu, mask);
			continue;
		}

		*etm_event_cpu_path_ptr(event_data, cpu) = path;
	}

	/* no sink found for any CPU - cannot trace */
	if (!sink)
		goto err;

	/* If we don't have any CPUs ready for tracing, abort */
	cpu = cpumask_first(mask);
	if (cpu >= nr_cpu_ids)
		goto err;

	if (!sink_ops(sink)->alloc_buffer || !sink_ops(sink)->free_buffer)
		goto err;

	/*
	 * Allocate the sink buffer for this session. All the sinks
	 * where this event can be scheduled are ensured to be of the
	 * same type. Thus the same sink configuration is used by the
	 * sinks.
	 */
	event_data->snk_config =
			sink_ops(sink)->alloc_buffer(sink, event, pages,
						     nr_pages, overwrite);
	if (!event_data->snk_config)
		goto err;

out:
	return event_data;

err:
	etm_free_aux(event_data);
	event_data = NULL;
	goto out;
}

static void etm_event_start(struct perf_event *event, int flags)
{
	int cpu = smp_processor_id();
	struct etm_event_data *event_data;
	struct etm_ctxt *ctxt = this_cpu_ptr(&etm_ctxt);
	struct perf_output_handle *handle = &ctxt->handle;
	struct coresight_device *sink, *csdev = per_cpu(csdev_src, cpu);
	struct list_head *path;

	if (!csdev)
		goto fail;

	/* Have we messed up our tracking ? */
	if (WARN_ON(ctxt->event_data))
		goto fail;

	/*
	 * Deal with the ring buffer API and get a handle on the
	 * session's information.
	 */
	event_data = perf_aux_output_begin(handle, event);
	if (!event_data)
		goto fail;

	/*
	 * Check if this ETM is allowed to trace, as decided
	 * at etm_setup_aux(). This could be due to an unreachable
	 * sink from this ETM. We can't do much in this case if
	 * the sink was specified or hinted to the driver. For
	 * now, simply don't record anything on this ETM.
	 */
	if (!cpumask_test_cpu(cpu, &event_data->mask))
		goto fail_end_stop;

	path = etm_event_cpu_path(event_data, cpu);
	/* We need a sink, no need to continue without one */
	sink = coresight_get_sink(path);
	if (WARN_ON_ONCE(!sink))
		goto fail_end_stop;

	/* Nothing will happen without a path */
	if (coresight_enable_path(path, CS_MODE_PERF, handle))
		goto fail_end_stop;

	/* Tell the perf core the event is alive */
	event->hw.state = 0;

	/* Finally enable the tracer */
	if (source_ops(csdev)->enable(csdev, event, CS_MODE_PERF))
		goto fail_disable_path;

	/* Save the event_data for this ETM */
	ctxt->event_data = event_data;
out:
	return;

fail_disable_path:
	coresight_disable_path(path);
fail_end_stop:
	perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
	perf_aux_output_end(handle, 0);
fail:
	event->hw.state = PERF_HES_STOPPED;
	goto out;
}

static void etm_event_stop(struct perf_event *event, int mode)
{
	int cpu = smp_processor_id();
	unsigned long size;
	struct coresight_device *sink, *csdev = per_cpu(csdev_src, cpu);
	struct etm_ctxt *ctxt = this_cpu_ptr(&etm_ctxt);
	struct perf_output_handle *handle = &ctxt->handle;
	struct etm_event_data *event_data;
	struct list_head *path;

	/*
	 * If we still have access to the event_data via handle,
	 * confirm that we haven't messed up the tracking.
	 */
	if (handle->event &&
	    WARN_ON(perf_get_aux(handle) != ctxt->event_data))
		return;

	event_data = ctxt->event_data;
	/* Clear the event_data as this ETM is stopping the trace. */
	ctxt->event_data = NULL;

	if (event->hw.state == PERF_HES_STOPPED)
		return;

	/* We must have a valid event_data for a running event */
	if (WARN_ON(!event_data))
		return;

	if (!csdev)
		return;

	path = etm_event_cpu_path(event_data, cpu);
	if (!path)
		return;

	sink = coresight_get_sink(path);
	if (!sink)
		return;

	/* stop tracer */
	source_ops(csdev)->disable(csdev, event);

	/* tell the core */
	event->hw.state = PERF_HES_STOPPED;

	/*
	 * If the handle is not bound to an event anymore
	 * (e.g, the sink driver was unable to restart the
	 * handle due to lack of buffer space), we don't
	 * have to do anything here.
	 */
	if (handle->event && (mode & PERF_EF_UPDATE)) {
		if (WARN_ON_ONCE(handle->event != event))
			return;

		/* update trace information */
		if (!sink_ops(sink)->update_buffer)
			return;

		size = sink_ops(sink)->update_buffer(sink, handle,
					      event_data->snk_config);
		perf_aux_output_end(handle, size);
	}

	/* Disabling the path make its elements available to other sessions */
	coresight_disable_path(path);
}

static int etm_event_add(struct perf_event *event, int mode)
{
	int ret = 0;
	struct hw_perf_event *hwc = &event->hw;

	if (mode & PERF_EF_START) {
		etm_event_start(event, 0);
		if (hwc->state & PERF_HES_STOPPED)
			ret = -EINVAL;
	} else {
		hwc->state = PERF_HES_STOPPED;
	}

	return ret;
}

static void etm_event_del(struct perf_event *event, int mode)
{
	etm_event_stop(event, PERF_EF_UPDATE);
}

static int etm_addr_filters_validate(struct list_head *filters)
{
	bool range = false, address = false;
	int index = 0;
	struct perf_addr_filter *filter;

	list_for_each_entry(filter, filters, entry) {
		/*
		 * No need to go further if there's no more
		 * room for filters.
		 */
		if (++index > ETM_ADDR_CMP_MAX)
			return -EOPNOTSUPP;

		/* filter::size==0 means single address trigger */
		if (filter->size) {
			/*
			 * The existing code relies on START/STOP filters
			 * being address filters.
			 */
			if (filter->action == PERF_ADDR_FILTER_ACTION_START ||
			    filter->action == PERF_ADDR_FILTER_ACTION_STOP)
				return -EOPNOTSUPP;

			range = true;
		} else
			address = true;

		/*
		 * At this time we don't allow range and start/stop filtering
		 * to cohabitate, they have to be mutually exclusive.
		 */
		if (range && address)
			return -EOPNOTSUPP;
	}

	return 0;
}

static void etm_addr_filters_sync(struct perf_event *event)
{
	struct perf_addr_filters_head *head = perf_event_addr_filters(event);
	unsigned long start, stop;
	struct perf_addr_filter_range *fr = event->addr_filter_ranges;
	struct etm_filters *filters = event->hw.addr_filters;
	struct etm_filter *etm_filter;
	struct perf_addr_filter *filter;
	int i = 0;

	list_for_each_entry(filter, &head->list, entry) {
		start = fr[i].start;
		stop = start + fr[i].size;
		etm_filter = &filters->etm_filter[i];

		switch (filter->action) {
		case PERF_ADDR_FILTER_ACTION_FILTER:
			etm_filter->start_addr = start;
			etm_filter->stop_addr = stop;
			etm_filter->type = ETM_ADDR_TYPE_RANGE;
			break;
		case PERF_ADDR_FILTER_ACTION_START:
			etm_filter->start_addr = start;
			etm_filter->type = ETM_ADDR_TYPE_START;
			break;
		case PERF_ADDR_FILTER_ACTION_STOP:
			etm_filter->stop_addr = stop;
			etm_filter->type = ETM_ADDR_TYPE_STOP;
			break;
		}
		i++;
	}

	filters->nr_filters = i;
}

int etm_perf_symlink(struct coresight_device *csdev, bool link)
{
	char entry[sizeof("cpu9999999")];
	int ret = 0, cpu = source_ops(csdev)->cpu_id(csdev);
	struct device *pmu_dev = etm_pmu.dev;
	struct device *cs_dev = &csdev->dev;

	sprintf(entry, "cpu%d", cpu);

	if (!etm_perf_up)
		return -EPROBE_DEFER;

	if (link) {
		ret = sysfs_create_link(&pmu_dev->kobj, &cs_dev->kobj, entry);
		if (ret)
			return ret;
		per_cpu(csdev_src, cpu) = csdev;
	} else {
		sysfs_remove_link(&pmu_dev->kobj, entry);
		per_cpu(csdev_src, cpu) = NULL;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(etm_perf_symlink);

static ssize_t etm_perf_sink_name_show(struct device *dev,
				       struct device_attribute *dattr,
				       char *buf)
{
	struct dev_ext_attribute *ea;

	ea = container_of(dattr, struct dev_ext_attribute, attr);
	return scnprintf(buf, PAGE_SIZE, "0x%lx\n", (unsigned long)(ea->var));
}

static struct dev_ext_attribute *
etm_perf_add_symlink_group(struct device *dev, const char *name, const char *group_name)
{
	struct dev_ext_attribute *ea;
	unsigned long hash;
	int ret;
	struct device *pmu_dev = etm_pmu.dev;

	if (!etm_perf_up)
		return ERR_PTR(-EPROBE_DEFER);

	ea = devm_kzalloc(dev, sizeof(*ea), GFP_KERNEL);
	if (!ea)
		return ERR_PTR(-ENOMEM);

	/*
	 * If this function is called adding a sink then the hash is used for
	 * sink selection - see function coresight_get_sink_by_id().
	 * If adding a configuration then the hash is used for selection in
	 * cscfg_activate_config()
	 */
	hash = hashlen_hash(hashlen_string(NULL, name));

	sysfs_attr_init(&ea->attr.attr);
	ea->attr.attr.name = devm_kstrdup(dev, name, GFP_KERNEL);
	if (!ea->attr.attr.name)
		return ERR_PTR(-ENOMEM);

	ea->attr.attr.mode = 0444;
	ea->var = (unsigned long *)hash;

	ret = sysfs_add_file_to_group(&pmu_dev->kobj,
				      &ea->attr.attr, group_name);

	return ret ? ERR_PTR(ret) : ea;
}

int etm_perf_add_symlink_sink(struct coresight_device *csdev)
{
	const char *name;
	struct device *dev = &csdev->dev;
	int err = 0;

	if (csdev->type != CORESIGHT_DEV_TYPE_SINK &&
	    csdev->type != CORESIGHT_DEV_TYPE_LINKSINK)
		return -EINVAL;

	if (csdev->ea != NULL)
		return -EINVAL;

	name = dev_name(dev);
	csdev->ea = etm_perf_add_symlink_group(dev, name, "sinks");
	if (IS_ERR(csdev->ea)) {
		err = PTR_ERR(csdev->ea);
		csdev->ea = NULL;
	} else
		csdev->ea->attr.show = etm_perf_sink_name_show;

	return err;
}

static void etm_perf_del_symlink_group(struct dev_ext_attribute *ea, const char *group_name)
{
	struct device *pmu_dev = etm_pmu.dev;

	sysfs_remove_file_from_group(&pmu_dev->kobj,
				     &ea->attr.attr, group_name);
}

void etm_perf_del_symlink_sink(struct coresight_device *csdev)
{
	if (csdev->type != CORESIGHT_DEV_TYPE_SINK &&
	    csdev->type != CORESIGHT_DEV_TYPE_LINKSINK)
		return;

	if (!csdev->ea)
		return;

	etm_perf_del_symlink_group(csdev->ea, "sinks");
	csdev->ea = NULL;
}

static ssize_t etm_perf_cscfg_event_show(struct device *dev,
					 struct device_attribute *dattr,
					 char *buf)
{
	struct dev_ext_attribute *ea;

	ea = container_of(dattr, struct dev_ext_attribute, attr);
	return scnprintf(buf, PAGE_SIZE, "configid=0x%lx\n", (unsigned long)(ea->var));
}

int etm_perf_add_symlink_cscfg(struct device *dev, struct cscfg_config_desc *config_desc)
{
	int err = 0;

	if (config_desc->event_ea != NULL)
		return 0;

	config_desc->event_ea = etm_perf_add_symlink_group(dev, config_desc->name, "events");

	/* set the show function to the custom cscfg event */
	if (!IS_ERR(config_desc->event_ea))
		config_desc->event_ea->attr.show = etm_perf_cscfg_event_show;
	else {
		err = PTR_ERR(config_desc->event_ea);
		config_desc->event_ea = NULL;
	}

	return err;
}

void etm_perf_del_symlink_cscfg(struct cscfg_config_desc *config_desc)
{
	if (!config_desc->event_ea)
		return;

	etm_perf_del_symlink_group(config_desc->event_ea, "events");
	config_desc->event_ea = NULL;
}

int __init etm_perf_init(void)
{
	int ret;

	etm_pmu.capabilities		= (PERF_PMU_CAP_EXCLUSIVE |
					   PERF_PMU_CAP_ITRACE);

	etm_pmu.attr_groups		= etm_pmu_attr_groups;
	etm_pmu.task_ctx_nr		= perf_sw_context;
	etm_pmu.read			= etm_event_read;
	etm_pmu.event_init		= etm_event_init;
	etm_pmu.setup_aux		= etm_setup_aux;
	etm_pmu.free_aux		= etm_free_aux;
	etm_pmu.start			= etm_event_start;
	etm_pmu.stop			= etm_event_stop;
	etm_pmu.add			= etm_event_add;
	etm_pmu.del			= etm_event_del;
	etm_pmu.addr_filters_sync	= etm_addr_filters_sync;
	etm_pmu.addr_filters_validate	= etm_addr_filters_validate;
	etm_pmu.nr_addr_filters		= ETM_ADDR_CMP_MAX;
	etm_pmu.module			= THIS_MODULE;

	ret = perf_pmu_register(&etm_pmu, CORESIGHT_ETM_PMU_NAME, -1);
	if (ret == 0)
		etm_perf_up = true;

	return ret;
}

void etm_perf_exit(void)
{
	perf_pmu_unregister(&etm_pmu);
}
