mirror of https://gitee.com/openkylin/linux.git
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. 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>
This commit is contained in:
parent
df81b43802
commit
6e736c60a9
|
@ -551,6 +551,7 @@ static int catu_probe(struct amba_device *adev, const struct amba_id *id)
|
|||
dev->platform_data = pdata;
|
||||
|
||||
drvdata->base = base;
|
||||
catu_desc.access = CSDEV_ACCESS_IOMEM(base);
|
||||
catu_desc.pdata = pdata;
|
||||
catu_desc.dev = dev;
|
||||
catu_desc.groups = catu_groups;
|
||||
|
|
|
@ -1458,6 +1458,48 @@ int coresight_timeout(void __iomem *addr, u32 offset, int position, int value)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(coresight_timeout);
|
||||
|
||||
u32 coresight_relaxed_read32(struct coresight_device *csdev, u32 offset)
|
||||
{
|
||||
return csdev_access_relaxed_read32(&csdev->access, offset);
|
||||
}
|
||||
|
||||
u32 coresight_read32(struct coresight_device *csdev, u32 offset)
|
||||
{
|
||||
return csdev_access_read32(&csdev->access, offset);
|
||||
}
|
||||
|
||||
void coresight_relaxed_write32(struct coresight_device *csdev,
|
||||
u32 val, u32 offset)
|
||||
{
|
||||
csdev_access_relaxed_write32(&csdev->access, val, offset);
|
||||
}
|
||||
|
||||
void coresight_write32(struct coresight_device *csdev, u32 val, u32 offset)
|
||||
{
|
||||
csdev_access_write32(&csdev->access, val, offset);
|
||||
}
|
||||
|
||||
u64 coresight_relaxed_read64(struct coresight_device *csdev, u32 offset)
|
||||
{
|
||||
return csdev_access_relaxed_read64(&csdev->access, offset);
|
||||
}
|
||||
|
||||
u64 coresight_read64(struct coresight_device *csdev, u32 offset)
|
||||
{
|
||||
return csdev_access_read64(&csdev->access, offset);
|
||||
}
|
||||
|
||||
void coresight_relaxed_write64(struct coresight_device *csdev,
|
||||
u64 val, u32 offset)
|
||||
{
|
||||
csdev_access_relaxed_write64(&csdev->access, val, offset);
|
||||
}
|
||||
|
||||
void coresight_write64(struct coresight_device *csdev, u64 val, u32 offset)
|
||||
{
|
||||
csdev_access_write64(&csdev->access, val, offset);
|
||||
}
|
||||
|
||||
/*
|
||||
* coresight_release_platform_data: Release references to the devices connected
|
||||
* to the output port of this device.
|
||||
|
@ -1522,6 +1564,7 @@ struct coresight_device *coresight_register(struct coresight_desc *desc)
|
|||
csdev->type = desc->type;
|
||||
csdev->subtype = desc->subtype;
|
||||
csdev->ops = desc->ops;
|
||||
csdev->access = desc->access;
|
||||
csdev->orphan = false;
|
||||
|
||||
csdev->dev.type = &coresight_dev_type[desc->type];
|
||||
|
|
|
@ -870,6 +870,7 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id)
|
|||
return PTR_ERR(base);
|
||||
|
||||
drvdata->base = base;
|
||||
cti_desc.access = CSDEV_ACCESS_IOMEM(base);
|
||||
|
||||
dev_set_drvdata(dev, drvdata);
|
||||
|
||||
|
|
|
@ -757,6 +757,7 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id)
|
|||
return PTR_ERR(base);
|
||||
|
||||
drvdata->base = base;
|
||||
desc.access = CSDEV_ACCESS_IOMEM(base);
|
||||
|
||||
spin_lock_init(&drvdata->spinlock);
|
||||
|
||||
|
|
|
@ -839,6 +839,7 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id)
|
|||
return PTR_ERR(base);
|
||||
|
||||
drvdata->base = base;
|
||||
desc.access = CSDEV_ACCESS_IOMEM(base);
|
||||
|
||||
spin_lock_init(&drvdata->spinlock);
|
||||
|
||||
|
|
|
@ -1626,6 +1626,7 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
|
|||
return PTR_ERR(base);
|
||||
|
||||
drvdata->base = base;
|
||||
desc.access = CSDEV_ACCESS_IOMEM(base);
|
||||
|
||||
spin_lock_init(&drvdata->spinlock);
|
||||
|
||||
|
|
|
@ -242,6 +242,7 @@ static int funnel_probe(struct device *dev, struct resource *res)
|
|||
}
|
||||
drvdata->base = base;
|
||||
desc.groups = coresight_funnel_groups;
|
||||
desc.access = CSDEV_ACCESS_IOMEM(base);
|
||||
}
|
||||
|
||||
dev_set_drvdata(dev, drvdata);
|
||||
|
|
|
@ -254,6 +254,7 @@ static int replicator_probe(struct device *dev, struct resource *res)
|
|||
}
|
||||
drvdata->base = base;
|
||||
desc.groups = replicator_groups;
|
||||
desc.access = CSDEV_ACCESS_IOMEM(base);
|
||||
}
|
||||
|
||||
if (fwnode_property_present(dev_fwnode(dev),
|
||||
|
|
|
@ -884,6 +884,7 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id)
|
|||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
drvdata->base = base;
|
||||
desc.access = CSDEV_ACCESS_IOMEM(base);
|
||||
|
||||
ret = stm_get_stimulus_area(dev, &ch_res);
|
||||
if (ret)
|
||||
|
|
|
@ -456,6 +456,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
|
|||
}
|
||||
|
||||
drvdata->base = base;
|
||||
desc.access = CSDEV_ACCESS_IOMEM(base);
|
||||
|
||||
spin_lock_init(&drvdata->spinlock);
|
||||
|
||||
|
|
|
@ -149,6 +149,7 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id)
|
|||
return PTR_ERR(base);
|
||||
|
||||
drvdata->base = base;
|
||||
desc.access = CSDEV_ACCESS_IOMEM(base);
|
||||
|
||||
/* Disable tpiu to support older devices */
|
||||
tpiu_disable_hw(drvdata);
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue