]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
coresight: cti: Access ASICCTL only when implemented
authorLeo Yan <leo.yan@arm.com>
Thu, 26 Feb 2026 09:23:51 +0000 (09:23 +0000)
committerSuzuki K Poulose <suzuki.poulose@arm.com>
Tue, 3 Mar 2026 10:23:45 +0000 (10:23 +0000)
According to the Arm ARM (DDI 0487 L.b), ASICCTL is implemented only
when CTIDEVID.EXTMUXNUM is non-zero.

Based on CTIDEVID.EXTMUXNUM, add a flag 'asicctl_impl' to indicate
whether the register is implemented, and access ASICCTL conditionally
based on the flag.

Allow the sysfs node to be visible only when the register is
implemented.

Reviewed-by: Mike Leach <mike.leach@arm.com>
Signed-off-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Link: https://lore.kernel.org/r/20260226-arm_coresight_cti_refactor_v1-v2-3-b30fada3cfec@arm.com
drivers/hwtracing/coresight/coresight-cti-core.c
drivers/hwtracing/coresight/coresight-cti-sysfs.c
drivers/hwtracing/coresight/coresight-cti.h

index 6a53c3ceebf41645e599017e076d12b8b158b10f..726970d852dee3b962e5147311dfadd0b741cfe0 100644 (file)
@@ -68,7 +68,8 @@ void cti_write_all_hw_regs(struct cti_drvdata *drvdata)
 
        /* other regs */
        writel_relaxed(config->ctigate, drvdata->base + CTIGATE);
-       writel_relaxed(config->asicctl, drvdata->base + ASICCTL);
+       if (config->asicctl_impl)
+               writel_relaxed(config->asicctl, drvdata->base + ASICCTL);
        writel_relaxed(config->ctiappset, drvdata->base + CTIAPPSET);
 
        /* re-enable CTI */
@@ -221,6 +222,8 @@ static void cti_set_default_config(struct device *dev,
        config->trig_filter_enable = true;
        config->ctigate = GENMASK(config->nr_ctm_channels - 1, 0);
        config->enable_req_count = 0;
+
+       config->asicctl_impl = !!FIELD_GET(GENMASK(4, 0), devid);
 }
 
 /*
index 9a997b2f090472761e9734fffc534663df8b06c6..c15a580f6e90f57b1376e0b883a27700966feb1a 100644 (file)
@@ -537,6 +537,18 @@ static struct attribute *coresight_cti_regs_attrs[] = {
        NULL,
 };
 
+static umode_t coresight_cti_regs_is_visible(struct kobject *kobj,
+                                            struct attribute *attr, int idx)
+{
+       struct device *dev = kobj_to_dev(kobj);
+       struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+       if (attr == &dev_attr_asicctl.attr && !drvdata->config.asicctl_impl)
+               return 0;
+
+       return attr->mode;
+}
+
 /* CTI channel x-trigger programming */
 static int
 cti_trig_op_parse(struct device *dev, enum cti_chan_op op,
@@ -1174,6 +1186,7 @@ static const struct attribute_group coresight_cti_mgmt_group = {
 
 static const struct attribute_group coresight_cti_regs_group = {
        .attrs = coresight_cti_regs_attrs,
+       .is_visible = coresight_cti_regs_is_visible,
        .name = "regs",
 };
 
index 45735526fe55b0e4746ba856443f0fcc807d82bb..a4b3968d8d3d19a20604fb09db14cf41962f5a79 100644 (file)
@@ -119,6 +119,7 @@ struct cti_device {
  * @nr_trig_max: Max number of trigger signals implemented on device.
  *              (max of trig_in or trig_out) - from ID register.
  * @nr_ctm_channels: number of available CTM channels - from ID register.
+ * @asicctl_impl: true if asicctl is implemented.
  * @enable_req_count: CTI is enabled alongside >=1 associated devices.
  * @hw_enabled: true if hw is currently enabled.
  * @hw_powered: true if associated cpu powered on, or no cpu.
@@ -140,6 +141,7 @@ struct cti_config {
        /* hardware description */
        int nr_ctm_channels;
        int nr_trig_max;
+       bool asicctl_impl;
 
        /* cti enable control */
        int enable_req_count;