Coresight components have 0 to 8 claim tag bits. ARM recommends 4 and the implemented claim tag protocol uses two of these.
If a component has insufficient claim tags then the protocol incorrectly returns an error when attempting to claim a component.
Fix by reading CLAIMSET to establish then actual number of claim tags and return success when attempting to claim a component were there are insufficient tags to implement the protocol.
Signed-off-by: Mike Leach mike.leach@linaro.org --- drivers/hwtracing/coresight/coresight-core.c | 26 ++++++++++++++++++++ drivers/hwtracing/coresight/coresight-priv.h | 8 ++++++ 2 files changed, 34 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index 3267192f0c1c..ce4eade8a1e3 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -131,6 +131,22 @@ coresight_find_out_connection(struct coresight_device *csdev, return ERR_PTR(-ENODEV); }
+/* + * Reading CLIAMSET returns a bitfield representing the number of claim tags + * implemented from bit 0 to bit nTag-1, valid bits set to 1. + * + * Claim protocol requires 2 bits so test for highest bit required, + * bit 1 - CORESIGHT_CLAIM_SELF_HOSTED_BIT + * + * return true if sufficient claim tags implemented for protocol + */ +static bool coresight_claim_tags_implemented_unlocked(struct csdev_access *csa) +{ + u32 claim_bits_impl = FIELD_GET(CORESIGHT_CLAIM_BITS_MAX_MASK, + csdev_access_relaxed_read32(csa, CORESIGHT_CLAIMSET)); + return ((claim_bits_impl & CORESIGHT_CLAIM_SELF_HOSTED_BIT) != 0); +} + static u32 coresight_read_claim_tags_unlocked(struct coresight_device *csdev) { return FIELD_GET(CORESIGHT_CLAIM_MASK, @@ -156,6 +172,9 @@ EXPORT_SYMBOL_GPL(coresight_clear_self_claim_tag);
void coresight_clear_self_claim_tag_unlocked(struct csdev_access *csa) { + if (!coresight_claim_tags_implemented_unlocked(csa)) + return; + csdev_access_relaxed_write32(csa, CORESIGHT_CLAIM_SELF_HOSTED, CORESIGHT_CLAIMCLR); isb(); @@ -181,6 +200,10 @@ int coresight_claim_device_unlocked(struct coresight_device *csdev) return -EINVAL;
csa = &csdev->access; + + if (!coresight_claim_tags_implemented_unlocked(csa)) + return 0; + tag = coresight_read_claim_tags_unlocked(csdev);
switch (tag) { @@ -237,6 +260,9 @@ void coresight_disclaim_device_unlocked(struct coresight_device *csdev) if (WARN_ON(!csdev)) return;
+ if (!coresight_claim_tags_implemented_unlocked(&csdev->access)) + return; + if (coresight_read_claim_tags_unlocked(csdev) == CORESIGHT_CLAIM_SELF_HOSTED) coresight_clear_self_claim_tag_unlocked(&csdev->access); else diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h index 33e22b1ba043..f93cbc9bb36a 100644 --- a/drivers/hwtracing/coresight/coresight-priv.h +++ b/drivers/hwtracing/coresight/coresight-priv.h @@ -41,6 +41,14 @@ extern const struct device_type coresight_dev_type[]; #define CORESIGHT_CLAIM_SELF_HOSTED 2 #define CORESIGHT_CLAIM_INVALID 3
+/* + * Coresight specification defines a maximum of 8 claim tag bits. + * The precise number is implementation defined, and may be obtained by + * reading the CLAIMSET register. + */ +#define CORESIGHT_CLAIM_BITS_MAX_MASK GENMASK(7, 0) +#define CORESIGHT_CLAIM_SELF_HOSTED_BIT BIT(1) + #define TIMEOUT_US 100 #define BMVAL(val, lsb, msb) ((val & GENMASK(msb, lsb)) >> lsb)