瀏覽代碼

coresight-tmc: Adding a status interface to sysfs

Knowing the state of various control register is always
useful for degging and tuning.  As such add an entry in
sysfs that expose to userspace the most important registers.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Mathieu Poirier 10 年之前
父節點
當前提交
a2d6e18493
共有 1 個文件被更改,包括 56 次插入0 次删除
  1. 56 0
      drivers/coresight/coresight-tmc.c

+ 56 - 0
drivers/coresight/coresight-tmc.c

@@ -565,6 +565,59 @@ static const struct file_operations tmc_fops = {
 	.llseek		= no_llseek,
 	.llseek		= no_llseek,
 };
 };
 
 
+static ssize_t status_show(struct device *dev,
+			   struct device_attribute *attr, char *buf)
+{
+	int ret;
+	unsigned long flags;
+	u32 tmc_rsz, tmc_sts, tmc_rrp, tmc_rwp, tmc_trg;
+	u32 tmc_ctl, tmc_ffsr, tmc_ffcr, tmc_mode, tmc_pscr;
+	u32 devid;
+	struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	ret = clk_prepare_enable(drvdata->clk);
+	if (ret)
+		goto out;
+
+	spin_lock_irqsave(&drvdata->spinlock, flags);
+	CS_UNLOCK(drvdata->base);
+
+	tmc_rsz = readl_relaxed(drvdata->base + TMC_RSZ);
+	tmc_sts = readl_relaxed(drvdata->base + TMC_STS);
+	tmc_rrp = readl_relaxed(drvdata->base + TMC_RRP);
+	tmc_rwp = readl_relaxed(drvdata->base + TMC_RWP);
+	tmc_trg = readl_relaxed(drvdata->base + TMC_TRG);
+	tmc_ctl = readl_relaxed(drvdata->base + TMC_CTL);
+	tmc_ffsr = readl_relaxed(drvdata->base + TMC_FFSR);
+	tmc_ffcr = readl_relaxed(drvdata->base + TMC_FFCR);
+	tmc_mode = readl_relaxed(drvdata->base + TMC_MODE);
+	tmc_pscr = readl_relaxed(drvdata->base + TMC_PSCR);
+	devid = readl_relaxed(drvdata->base + CORESIGHT_DEVID);
+
+	CS_LOCK(drvdata->base);
+	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+
+	clk_disable_unprepare(drvdata->clk);
+
+	return sprintf(buf,
+		       "Depth:\t\t0x%x\n"
+		       "Status:\t\t0x%x\n"
+		       "RAM read ptr:\t0x%x\n"
+		       "RAM wrt ptr:\t0x%x\n"
+		       "Trigger cnt:\t0x%x\n"
+		       "Control:\t0x%x\n"
+		       "Flush status:\t0x%x\n"
+		       "Flush ctrl:\t0x%x\n"
+		       "Mode:\t\t0x%x\n"
+		       "PSRC:\t\t0x%x\n"
+		       "DEVID:\t\t0x%x\n",
+			tmc_rsz, tmc_sts, tmc_rrp, tmc_rwp, tmc_trg,
+			tmc_ctl, tmc_ffsr, tmc_ffcr, tmc_mode, tmc_pscr, devid);
+out:
+	return -EINVAL;
+}
+static DEVICE_ATTR_RO(status);
+
 static ssize_t trigger_cntr_show(struct device *dev,
 static ssize_t trigger_cntr_show(struct device *dev,
 			    struct device_attribute *attr, char *buf)
 			    struct device_attribute *attr, char *buf)
 {
 {
@@ -593,18 +646,21 @@ static DEVICE_ATTR_RW(trigger_cntr);
 
 
 static struct attribute *coresight_etb_attrs[] = {
 static struct attribute *coresight_etb_attrs[] = {
 	&dev_attr_trigger_cntr.attr,
 	&dev_attr_trigger_cntr.attr,
+	&dev_attr_status.attr,
 	NULL,
 	NULL,
 };
 };
 ATTRIBUTE_GROUPS(coresight_etb);
 ATTRIBUTE_GROUPS(coresight_etb);
 
 
 static struct attribute *coresight_etr_attrs[] = {
 static struct attribute *coresight_etr_attrs[] = {
 	&dev_attr_trigger_cntr.attr,
 	&dev_attr_trigger_cntr.attr,
+	&dev_attr_status.attr,
 	NULL,
 	NULL,
 };
 };
 ATTRIBUTE_GROUPS(coresight_etr);
 ATTRIBUTE_GROUPS(coresight_etr);
 
 
 static struct attribute *coresight_etf_attrs[] = {
 static struct attribute *coresight_etf_attrs[] = {
 	&dev_attr_trigger_cntr.attr,
 	&dev_attr_trigger_cntr.attr,
+	&dev_attr_status.attr,
 	NULL,
 	NULL,
 };
 };
 ATTRIBUTE_GROUPS(coresight_etf);
 ATTRIBUTE_GROUPS(coresight_etf);