UPSTREAM: coresight: Introduce device access abstraction
We are about to introduce support for sysreg access to ETMv4.4+ component. Since there are generic routines that access the registers (e.g, CS_LOCK/UNLOCK , claim/disclaim operations, timeout) and in order to preserve the logic of these operations at a single place we introduce an abstraction layer for the accesses to a given device. Bug: 174685394 Link: https://lore.kernel.org/r/20210110224850.1880240-4-suzuki.poulose@arm.com Cc: Mike Leach <mike.leach@linaro.org> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org> Link: https://lore.kernel.org/r/20210201181351.1475223-6-mathieu.poirier@linaro.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> (cherry picked from commit 6e736c60a9fe905b3e4f4b07171a31ad602d56d2) Signed-off-by: Qais Yousef <qais.yousef@arm.com> Change-Id: Ie1e48d480cb73155797f7c335db603078ac32fdf
This commit is contained in:

committed by
Todd Kjos

parent
c7a868d7a7
commit
a74e3236dd
@@ -7,6 +7,7 @@
|
||||
#define _LINUX_CORESIGHT_H
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/perf_event.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
@@ -114,6 +115,32 @@ struct coresight_platform_data {
|
||||
struct coresight_connection *conns;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct csdev_access - Abstraction of a CoreSight device access.
|
||||
*
|
||||
* @io_mem : True if the device has memory mapped I/O
|
||||
* @base : When io_mem == true, base address of the component
|
||||
* @read : Read from the given "offset" of the given instance.
|
||||
* @write : Write "val" to the given "offset".
|
||||
*/
|
||||
struct csdev_access {
|
||||
bool io_mem;
|
||||
union {
|
||||
void __iomem *base;
|
||||
struct {
|
||||
u64 (*read)(u32 offset, bool relaxed, bool _64bit);
|
||||
void (*write)(u64 val, u32 offset, bool relaxed,
|
||||
bool _64bit);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
#define CSDEV_ACCESS_IOMEM(_addr) \
|
||||
((struct csdev_access) { \
|
||||
.io_mem = true, \
|
||||
.base = (_addr), \
|
||||
})
|
||||
|
||||
/**
|
||||
* struct coresight_desc - description of a component required from drivers
|
||||
* @type: as defined by @coresight_dev_type.
|
||||
@@ -125,6 +152,7 @@ struct coresight_platform_data {
|
||||
* @groups: operations specific to this component. These will end up
|
||||
* in the component's sysfs sub-directory.
|
||||
* @name: name for the coresight device, also shown under sysfs.
|
||||
* @access: Describe access to the device
|
||||
*/
|
||||
struct coresight_desc {
|
||||
enum coresight_dev_type type;
|
||||
@@ -134,6 +162,7 @@ struct coresight_desc {
|
||||
struct device *dev;
|
||||
const struct attribute_group **groups;
|
||||
const char *name;
|
||||
struct csdev_access access;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -173,7 +202,8 @@ struct coresight_sysfs_link {
|
||||
* @type: as defined by @coresight_dev_type.
|
||||
* @subtype: as defined by @coresight_dev_subtype.
|
||||
* @ops: generic operations for this component, as defined
|
||||
by @coresight_ops.
|
||||
* by @coresight_ops.
|
||||
* @access: Device i/o access abstraction for this device.
|
||||
* @dev: The device entity associated to this component.
|
||||
* @refcnt: keep track of what is in use.
|
||||
* @orphan: true if the component has connections that haven't been linked.
|
||||
@@ -195,6 +225,7 @@ struct coresight_device {
|
||||
enum coresight_dev_type type;
|
||||
union coresight_dev_subtype subtype;
|
||||
const struct coresight_ops *ops;
|
||||
struct csdev_access access;
|
||||
struct device dev;
|
||||
atomic_t *refcnt;
|
||||
bool orphan;
|
||||
@@ -326,6 +357,104 @@ struct coresight_ops {
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_CORESIGHT)
|
||||
|
||||
static inline u32 csdev_access_relaxed_read32(struct csdev_access *csa,
|
||||
u32 offset)
|
||||
{
|
||||
if (likely(csa->io_mem))
|
||||
return readl_relaxed(csa->base + offset);
|
||||
|
||||
return csa->read(offset, true, false);
|
||||
}
|
||||
|
||||
static inline u32 csdev_access_read32(struct csdev_access *csa, u32 offset)
|
||||
{
|
||||
if (likely(csa->io_mem))
|
||||
return readl(csa->base + offset);
|
||||
|
||||
return csa->read(offset, false, false);
|
||||
}
|
||||
|
||||
static inline void csdev_access_relaxed_write32(struct csdev_access *csa,
|
||||
u32 val, u32 offset)
|
||||
{
|
||||
if (likely(csa->io_mem))
|
||||
writel_relaxed(val, csa->base + offset);
|
||||
else
|
||||
csa->write(val, offset, true, false);
|
||||
}
|
||||
|
||||
static inline void csdev_access_write32(struct csdev_access *csa, u32 val, u32 offset)
|
||||
{
|
||||
if (likely(csa->io_mem))
|
||||
writel(val, csa->base + offset);
|
||||
else
|
||||
csa->write(val, offset, false, false);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
|
||||
static inline u64 csdev_access_relaxed_read64(struct csdev_access *csa,
|
||||
u32 offset)
|
||||
{
|
||||
if (likely(csa->io_mem))
|
||||
return readq_relaxed(csa->base + offset);
|
||||
|
||||
return csa->read(offset, true, true);
|
||||
}
|
||||
|
||||
static inline u64 csdev_access_read64(struct csdev_access *csa, u32 offset)
|
||||
{
|
||||
if (likely(csa->io_mem))
|
||||
return readq(csa->base + offset);
|
||||
|
||||
return csa->read(offset, false, true);
|
||||
}
|
||||
|
||||
static inline void csdev_access_relaxed_write64(struct csdev_access *csa,
|
||||
u64 val, u32 offset)
|
||||
{
|
||||
if (likely(csa->io_mem))
|
||||
writeq_relaxed(val, csa->base + offset);
|
||||
else
|
||||
csa->write(val, offset, true, true);
|
||||
}
|
||||
|
||||
static inline void csdev_access_write64(struct csdev_access *csa, u64 val, u32 offset)
|
||||
{
|
||||
if (likely(csa->io_mem))
|
||||
writeq(val, csa->base + offset);
|
||||
else
|
||||
csa->write(val, offset, false, true);
|
||||
}
|
||||
|
||||
#else /* !CONFIG_64BIT */
|
||||
|
||||
static inline u64 csdev_access_relaxed_read64(struct csdev_access *csa,
|
||||
u32 offset)
|
||||
{
|
||||
WARN_ON(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline u64 csdev_access_read64(struct csdev_access *csa, u32 offset)
|
||||
{
|
||||
WARN_ON(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void csdev_access_relaxed_write64(struct csdev_access *csa,
|
||||
u64 val, u32 offset)
|
||||
{
|
||||
WARN_ON(1);
|
||||
}
|
||||
|
||||
static inline void csdev_access_write64(struct csdev_access *csa, u64 val, u32 offset)
|
||||
{
|
||||
WARN_ON(1);
|
||||
}
|
||||
#endif /* CONFIG_64BIT */
|
||||
|
||||
extern struct coresight_device *
|
||||
coresight_register(struct coresight_desc *desc);
|
||||
extern void coresight_unregister(struct coresight_device *csdev);
|
||||
@@ -343,6 +472,18 @@ extern char *coresight_alloc_device_name(struct coresight_dev_list *devs,
|
||||
struct device *dev);
|
||||
|
||||
extern bool coresight_loses_context_with_cpu(struct device *dev);
|
||||
|
||||
u32 coresight_relaxed_read32(struct coresight_device *csdev, u32 offset);
|
||||
u32 coresight_read32(struct coresight_device *csdev, u32 offset);
|
||||
void coresight_write32(struct coresight_device *csdev, u32 val, u32 offset);
|
||||
void coresight_relaxed_write32(struct coresight_device *csdev,
|
||||
u32 val, u32 offset);
|
||||
u64 coresight_relaxed_read64(struct coresight_device *csdev, u32 offset);
|
||||
u64 coresight_read64(struct coresight_device *csdev, u32 offset);
|
||||
void coresight_relaxed_write64(struct coresight_device *csdev,
|
||||
u64 val, u32 offset);
|
||||
void coresight_write64(struct coresight_device *csdev, u64 val, u32 offset);
|
||||
|
||||
#else
|
||||
static inline struct coresight_device *
|
||||
coresight_register(struct coresight_desc *desc) { return NULL; }
|
||||
@@ -369,10 +510,54 @@ static inline bool coresight_loses_context_with_cpu(struct device *dev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline u32 coresight_relaxed_read32(struct coresight_device *csdev, u32 offset)
|
||||
{
|
||||
WARN_ON_ONCE(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline u32 coresight_read32(struct coresight_device *csdev, u32 offset)
|
||||
{
|
||||
WARN_ON_ONCE(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void coresight_write32(struct coresight_device *csdev, u32 val, u32 offset)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void coresight_relaxed_write32(struct coresight_device *csdev,
|
||||
u32 val, u32 offset)
|
||||
{
|
||||
}
|
||||
|
||||
static inline u64 coresight_relaxed_read64(struct coresight_device *csdev,
|
||||
u32 offset)
|
||||
{
|
||||
WARN_ON_ONCE(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline u64 coresight_read64(struct coresight_device *csdev, u32 offset)
|
||||
{
|
||||
WARN_ON_ONCE(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void coresight_relaxed_write64(struct coresight_device *csdev,
|
||||
u64 val, u32 offset)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void coresight_write64(struct coresight_device *csdev, u64 val, u32 offset)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* IS_ENABLED(CONFIG_CORESIGHT) */
|
||||
|
||||
extern int coresight_get_cpu(struct device *dev);
|
||||
|
||||
struct coresight_platform_data *coresight_get_platform_data(struct device *dev);
|
||||
|
||||
#endif
|
||||
#endif /* _LINUX_COREISGHT_H */
|
||||
|
Reference in New Issue
Block a user