mirror of
https://github.com/torvalds/linux.git
synced 2024-11-19 02:21:47 +00:00
d52c9750f1
When using coresight from the perf interface sinks are specified as part of the perf command line. As such the sink needs to be disabled once it has been acknowledged by the coresight framework. Otherwise the sink stays enabled, which may interfere with other sessions. This patch removes the sink selection check from the build path process and make it a function on it's own. The function is then used when operating from sysFS or perf to determine what sink has been selected. If operated from perf the status of the "enable_sink" flag is reset so that concurrent session can use a different sink. When used from sysFS the status of the flag is left untouched since users have full control. The implementation doesn't handle a scenario where a sink has been enabled from sysFS and another sink is selected from the perf command line as both modes of operation are mutually exclusive. Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
128 lines
3.6 KiB
C
128 lines
3.6 KiB
C
/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 and
|
|
* only version 2 as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#ifndef _CORESIGHT_PRIV_H
|
|
#define _CORESIGHT_PRIV_H
|
|
|
|
#include <linux/bitops.h>
|
|
#include <linux/io.h>
|
|
#include <linux/coresight.h>
|
|
#include <linux/pm_runtime.h>
|
|
|
|
/*
|
|
* Coresight management registers (0xf00-0xfcc)
|
|
* 0xfa0 - 0xfa4: Management registers in PFTv1.0
|
|
* Trace registers in PFTv1.1
|
|
*/
|
|
#define CORESIGHT_ITCTRL 0xf00
|
|
#define CORESIGHT_CLAIMSET 0xfa0
|
|
#define CORESIGHT_CLAIMCLR 0xfa4
|
|
#define CORESIGHT_LAR 0xfb0
|
|
#define CORESIGHT_LSR 0xfb4
|
|
#define CORESIGHT_AUTHSTATUS 0xfb8
|
|
#define CORESIGHT_DEVID 0xfc8
|
|
#define CORESIGHT_DEVTYPE 0xfcc
|
|
|
|
#define TIMEOUT_US 100
|
|
#define BMVAL(val, lsb, msb) ((val & GENMASK(msb, lsb)) >> lsb)
|
|
|
|
#define ETM_MODE_EXCL_KERN BIT(30)
|
|
#define ETM_MODE_EXCL_USER BIT(31)
|
|
|
|
typedef u32 (*coresight_read_fn)(const struct device *, u32 offset);
|
|
#define coresight_simple_func(type, func, name, offset) \
|
|
static ssize_t name##_show(struct device *_dev, \
|
|
struct device_attribute *attr, char *buf) \
|
|
{ \
|
|
type *drvdata = dev_get_drvdata(_dev->parent); \
|
|
coresight_read_fn fn = func; \
|
|
u32 val; \
|
|
pm_runtime_get_sync(_dev->parent); \
|
|
if (fn) \
|
|
val = fn(_dev->parent, offset); \
|
|
else \
|
|
val = readl_relaxed(drvdata->base + offset); \
|
|
pm_runtime_put_sync(_dev->parent); \
|
|
return scnprintf(buf, PAGE_SIZE, "0x%x\n", val); \
|
|
} \
|
|
static DEVICE_ATTR_RO(name)
|
|
|
|
enum etm_addr_type {
|
|
ETM_ADDR_TYPE_NONE,
|
|
ETM_ADDR_TYPE_SINGLE,
|
|
ETM_ADDR_TYPE_RANGE,
|
|
ETM_ADDR_TYPE_START,
|
|
ETM_ADDR_TYPE_STOP,
|
|
};
|
|
|
|
enum cs_mode {
|
|
CS_MODE_DISABLED,
|
|
CS_MODE_SYSFS,
|
|
CS_MODE_PERF,
|
|
};
|
|
|
|
/**
|
|
* struct cs_buffer - keep track of a recording session' specifics
|
|
* @cur: index of the current buffer
|
|
* @nr_pages: max number of pages granted to us
|
|
* @offset: offset within the current buffer
|
|
* @data_size: how much we collected in this run
|
|
* @lost: other than zero if we had a HW buffer wrap around
|
|
* @snapshot: is this run in snapshot mode
|
|
* @data_pages: a handle the ring buffer
|
|
*/
|
|
struct cs_buffers {
|
|
unsigned int cur;
|
|
unsigned int nr_pages;
|
|
unsigned long offset;
|
|
local_t data_size;
|
|
local_t lost;
|
|
bool snapshot;
|
|
void **data_pages;
|
|
};
|
|
|
|
static inline void CS_LOCK(void __iomem *addr)
|
|
{
|
|
do {
|
|
/* Wait for things to settle */
|
|
mb();
|
|
writel_relaxed(0x0, addr + CORESIGHT_LAR);
|
|
} while (0);
|
|
}
|
|
|
|
static inline void CS_UNLOCK(void __iomem *addr)
|
|
{
|
|
do {
|
|
writel_relaxed(CORESIGHT_UNLOCK, addr + CORESIGHT_LAR);
|
|
/* Make sure everyone has seen this */
|
|
mb();
|
|
} while (0);
|
|
}
|
|
|
|
void coresight_disable_path(struct list_head *path);
|
|
int coresight_enable_path(struct list_head *path, u32 mode);
|
|
struct coresight_device *coresight_get_sink(struct list_head *path);
|
|
struct coresight_device *coresight_get_enabled_sink(bool reset);
|
|
struct list_head *coresight_build_path(struct coresight_device *csdev,
|
|
struct coresight_device *sink);
|
|
void coresight_release_path(struct list_head *path);
|
|
|
|
#ifdef CONFIG_CORESIGHT_SOURCE_ETM3X
|
|
extern int etm_readl_cp14(u32 off, unsigned int *val);
|
|
extern int etm_writel_cp14(u32 off, u32 val);
|
|
#else
|
|
static inline int etm_readl_cp14(u32 off, unsigned int *val) { return 0; }
|
|
static inline int etm_writel_cp14(u32 off, u32 val) { return 0; }
|
|
#endif
|
|
|
|
#endif
|