drivers/hwtracing/coresight/coresight-cti-sysfs.c

Source file repositories/reference/linux-study-clean/drivers/hwtracing/coresight/coresight-cti-sysfs.c

File Facts

System
Linux kernel
Corpus path
drivers/hwtracing/coresight/coresight-cti-sysfs.c
Extension
.c
Size
31776 bytes
Lines
1194
Domain
Driver Families
Bucket
drivers/hwtracing
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (cti_is_active(config)) {
			val = cti_read_single_reg(drvdata, reg_offset);
			if (pcached_val)
				*pcached_val = val;
		} else if (pcached_val) {
			val = *pcached_val;
		}
	}

	return sprintf(buf, "%#x\n", val);
}

/*
 * Store a simple 32 bit value.
 * If pcached_val not NULL, then copy to here too,
 * if reg_offset >= 0 then write through if enabled.
 */
static ssize_t cti_reg32_store(struct device *dev, const char *buf,
			       size_t size, u32 *pcached_val, int reg_offset)
{
	unsigned long val;
	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
	struct cti_config *config = &drvdata->config;

	if (kstrtoul(buf, 0, &val))
		return -EINVAL;

	if (reg_offset < 0)
		return -EINVAL;

	scoped_guard(raw_spinlock_irqsave, &drvdata->spinlock) {
		/* local store */
		if (pcached_val)
			*pcached_val = (u32)val;

		/* write through if offset and enabled */
		if (cti_is_active(config))
			cti_write_single_reg(drvdata, reg_offset, val);
	}

	return size;
}

/* Standard macro for simple rw cti config registers */
#define cti_config_reg32_rw(name, cfgname, offset)			\
static ssize_t name##_show(struct device *dev,				\
			   struct device_attribute *attr,		\
			   char *buf)					\
{									\
	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);	\
	return cti_reg32_show(dev, buf,					\
			      &drvdata->config.cfgname, offset);	\
}									\
									\
static ssize_t name##_store(struct device *dev,				\
			    struct device_attribute *attr,		\
			    const char *buf, size_t size)		\
{									\
	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);	\
	return cti_reg32_store(dev, buf, size,				\
			       &drvdata->config.cfgname, offset);	\
}									\
static DEVICE_ATTR_RW(name)

static ssize_t inout_sel_show(struct device *dev,
			      struct device_attribute *attr,
			      char *buf)
{
	u32 val;
	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);

	val = (u32)drvdata->config.ctiinout_sel;
	return sprintf(buf, "%d\n", val);
}

static ssize_t inout_sel_store(struct device *dev,
			       struct device_attribute *attr,
			       const char *buf, size_t size)
{
	unsigned long val;
	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
	struct cti_config *config = &drvdata->config;

	if (kstrtoul(buf, 0, &val))
		return -EINVAL;
	if (val >= config->nr_trig_max)
		return -EINVAL;

	guard(raw_spinlock_irqsave)(&drvdata->spinlock);

Annotation

Implementation Notes