Re: [PATCH v10 3/7] qcom-tgu: Add signal priority support
From: Songwei Chai
Date: Mon Jan 26 2026 - 21:24:08 EST
On 1/13/2026 7:09 PM, Konrad Dybcio wrote:
On 1/9/26 3:11 AM, Songwei Chai wrote:Sure, Konrad.
Like circuit of a Logic analyzer, in TGU, the requirement could be
configured in each step and the trigger will be created once the
requirements are met. Add priority functionality here to sort the
signals into different priorities. The signal which is wanted could
be configured in each step's priority node, the larger number means
the higher priority and the signal with higher priority will be sensed
more preferentially.
Signed-off-by: Songwei Chai <songwei.chai@xxxxxxxxxxxxxxxx>
---
[...]
+static ssize_t tgu_dataset_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct tgu_drvdata *tgu_drvdata = dev_get_drvdata(dev);
+ struct tgu_attribute *tgu_attr =
+ container_of(attr, struct tgu_attribute, attr);
+ unsigned long val;
+ int index;
+
+ ret = kstrtoul(buf, 0, &val);
+ if (ret)
+ return ret;
+
+ guard(spinlock)(&tgu_drvdata->lock);
+ index = calculate_array_location(tgu_drvdata, tgu_attr->step_index,
+ tgu_attr->operation_index,
+ tgu_attr->reg_num);
+
+ tgu_drvdata->value_table->priority[index] = val;
+ return size;
Style: some functions have a \n before return, some don't. The former
is preferred
I will update and pay more attention next time.
I agree that the expanded form is clearer step-by-step, but I intentionally kept the current version as it keeps the bounds checks localized and avoids multiple early returns in this simple case.
+static umode_t tgu_node_visible(struct kobject *kobject,
+ struct attribute *attr,
+ int n)
+{
+ struct device *dev = kobj_to_dev(kobject);
+ struct tgu_drvdata *drvdata = dev_get_drvdata(dev);
+ struct device_attribute *dev_attr =
+ container_of(attr, struct device_attribute, attr);
+ struct tgu_attribute *tgu_attr =
+ container_of(dev_attr, struct tgu_attribute, attr);
+ int ret = SYSFS_GROUP_INVISIBLE;
+
+ if (tgu_attr->step_index < drvdata->max_step) {
+ ret = (tgu_attr->reg_num < drvdata->max_reg) ?
+ attr->mode : 0;
+ }
+ return ret;
This is very convoluted
How about:
if (tgu_attr->step_index >= drvdata->max_step)
return 0;
if (tgu_attr->reg_num >= drvdata->max_reg)
return 0;
return attr->mode;
?
[...]
I find the conditional expression still reasonably readable here, but I’m happy to revisit this if you feel strongly about the style.
Marked, will update.+static void tgu_set_reg_number(struct tgu_drvdata *drvdata)
+{
+ int num_sense_input;
+ int num_reg;
+ u32 devid;
+
+ devid = readl(drvdata->base + TGU_DEVID);
+
+ num_sense_input = TGU_DEVID_SENSE_INPUT(devid);
+ if (((num_sense_input * NUMBER_BITS_EACH_SIGNAL) % LENGTH_REGISTER) == 0)
+ num_reg = (num_sense_input * NUMBER_BITS_EACH_SIGNAL) / LENGTH_REGISTER;
+ else
+ num_reg = ((num_sense_input * NUMBER_BITS_EACH_SIGNAL) / LENGTH_REGISTER) + 1;
num_reg = base case
if (num_sense_input * NUMBER_BITS_EACH_SIGNAL) % LENGTH_REGISTER)
num_reg++;
?
[...]Marked, will update.
@@ -112,6 +250,8 @@ static int tgu_probe(struct amba_device *adev, const struct amba_id *id)
{
struct device *dev = &adev->dev;
struct tgu_drvdata *drvdata;
+ size_t priority_size;
+ unsigned int *priority;
reverse-Christmas-tree would be nice
Marked, will update.int ret;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
@@ -127,12 +267,32 @@ static int tgu_probe(struct amba_device *adev, const struct amba_id *id)
spin_lock_init(&drvdata->lock);
+ tgu_set_reg_number(drvdata);
+ tgu_set_steps(drvdata);
+
ret = sysfs_create_groups(&dev->kobj, tgu_attr_groups);
if (ret) {
dev_err(dev, "failed to create sysfs groups: %d\n", ret);
return ret;
}
+ drvdata->value_table =
+ devm_kzalloc(dev, sizeof(*drvdata->value_table), GFP_KERNEL);
+ if (!drvdata->value_table)
+ return -ENOMEM;
+
+ priority_size = MAX_PRIORITY * drvdata->max_reg *
+ drvdata->max_step *
+ sizeof(*(drvdata->value_table->priority));
+
+ priority = devm_kzalloc(dev, priority_size, GFP_KERNEL);
+
+ if (!priority)
stray \n above
Marked, will update.
[...]
+#define BMVAL(val, lsb, msb) ((val & GENMASK(msb, lsb)) >> lsb)
+#define TGU_DEVID_SENSE_INPUT(devid_val) ((int) BMVAL(devid_val, 10, 17))
+#define TGU_DEVID_STEPS(devid_val) ((int)BMVAL(devid_val, 3, 6))
+#define NUMBER_BITS_EACH_SIGNAL 4
"TGU_BITS_PER_SIGNAL"
Konrad