drivers/hwtracing/coresight/ultrasoc-smb.c

Source file repositories/reference/linux-study-clean/drivers/hwtracing/coresight/ultrasoc-smb.c

File Facts

System
Linux kernel
Corpus path
drivers/hwtracing/coresight/ultrasoc-smb.c
Extension
.c
Size
14926 bytes
Lines
610
Domain
Driver Families
Bucket
drivers/hwtracing
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static const struct file_operations smb_fops = {
	.owner		= THIS_MODULE,
	.open		= smb_open,
	.read		= smb_read,
	.release	= smb_release,
};

static ssize_t buf_size_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	struct smb_drv_data *drvdata = dev_get_drvdata(dev->parent);

	return sysfs_emit(buf, "0x%lx\n", drvdata->sdb.buf_size);
}
static DEVICE_ATTR_RO(buf_size);

static struct attribute *smb_sink_attrs[] = {
	coresight_simple_reg32(read_pos, SMB_LB_RD_ADDR_REG),
	coresight_simple_reg32(write_pos, SMB_LB_WR_ADDR_REG),
	coresight_simple_reg32(buf_status, SMB_LB_INT_STS_REG),
	&dev_attr_buf_size.attr,
	NULL
};

static const struct attribute_group smb_sink_group = {
	.attrs = smb_sink_attrs,
	.name = "mgmt",
};

static const struct attribute_group *smb_sink_groups[] = {
	&smb_sink_group,
	NULL
};

static void smb_enable_hw(struct smb_drv_data *drvdata)
{
	writel(SMB_GLB_EN_HW_ENABLE, drvdata->base + SMB_GLB_EN_REG);
}

static void smb_disable_hw(struct smb_drv_data *drvdata)
{
	writel(0x0, drvdata->base + SMB_GLB_EN_REG);
}

static void smb_enable_sysfs(struct coresight_device *csdev)
{
	struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);

	if (coresight_get_mode(csdev) != CS_MODE_DISABLED)
		return;

	smb_enable_hw(drvdata);
	coresight_set_mode(csdev, CS_MODE_SYSFS);
}

static int smb_enable_perf(struct coresight_device *csdev,
			   struct coresight_path *path)
{
	struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
	struct perf_output_handle *handle = path->handle;
	struct cs_buffers *buf = etm_perf_sink_config(handle);
	pid_t pid;

	if (!buf)
		return -EINVAL;

	/* Get a handle on the pid of the target process */
	pid = buf->pid;

	/* Device is already in used by other session */
	if (drvdata->pid != -1 && drvdata->pid != pid)
		return -EBUSY;

	if (drvdata->pid == -1) {
		smb_enable_hw(drvdata);
		drvdata->pid = pid;
		coresight_set_mode(csdev, CS_MODE_PERF);
	}

	return 0;
}

static int smb_enable(struct coresight_device *csdev, enum cs_mode mode,
		      struct coresight_path *path)
{
	struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
	int ret = 0;

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

Annotation

Implementation Notes