drivers/base/soc.c

Source file repositories/reference/linux-study-clean/drivers/base/soc.c

File Facts

System
Linux kernel
Corpus path
drivers/base/soc.c
Extension
.c
Size
7120 bytes
Lines
280
Domain
Driver Families
Bucket
drivers/base
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 bus_type soc_bus_type = {
	.name  = "soc",
};
static bool soc_bus_registered;

static DEVICE_ATTR(machine,		0444, soc_info_show,  NULL);
static DEVICE_ATTR(family,		0444, soc_info_show,  NULL);
static DEVICE_ATTR(serial_number,	0444, soc_info_show,  NULL);
static DEVICE_ATTR(soc_id,		0444, soc_info_show,  NULL);
static DEVICE_ATTR(revision,		0444, soc_info_show,  NULL);

struct device *soc_device_to_device(struct soc_device *soc_dev)
{
	return &soc_dev->dev;
}

static umode_t soc_attribute_mode(struct kobject *kobj,
				struct attribute *attr,
				int index)
{
	struct device *dev = kobj_to_dev(kobj);
	struct soc_device *soc_dev = container_of(dev, struct soc_device, dev);

	if ((attr == &dev_attr_machine.attr) && soc_dev->attr->machine)
		return attr->mode;
	if ((attr == &dev_attr_family.attr) && soc_dev->attr->family)
		return attr->mode;
	if ((attr == &dev_attr_revision.attr) && soc_dev->attr->revision)
		return attr->mode;
	if ((attr == &dev_attr_serial_number.attr) && soc_dev->attr->serial_number)
		return attr->mode;
	if ((attr == &dev_attr_soc_id.attr) && soc_dev->attr->soc_id)
		return attr->mode;

	/* Unknown or unfilled attribute */
	return 0;
}

static ssize_t soc_info_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	struct soc_device *soc_dev = container_of(dev, struct soc_device, dev);
	const char *output;

	if (attr == &dev_attr_machine)
		output = soc_dev->attr->machine;
	else if (attr == &dev_attr_family)
		output = soc_dev->attr->family;
	else if (attr == &dev_attr_revision)
		output = soc_dev->attr->revision;
	else if (attr == &dev_attr_serial_number)
		output = soc_dev->attr->serial_number;
	else if (attr == &dev_attr_soc_id)
		output = soc_dev->attr->soc_id;
	else
		return -EINVAL;

	return sysfs_emit(buf, "%s\n", output);
}

static struct attribute *soc_attr[] = {
	&dev_attr_machine.attr,
	&dev_attr_family.attr,
	&dev_attr_serial_number.attr,
	&dev_attr_soc_id.attr,
	&dev_attr_revision.attr,
	NULL,
};

static const struct attribute_group soc_attr_group = {
	.attrs = soc_attr,
	.is_visible = soc_attribute_mode,
};

static void soc_release(struct device *dev)
{
	struct soc_device *soc_dev = container_of(dev, struct soc_device, dev);

	ida_free(&soc_ida, soc_dev->soc_dev_num);
	kfree(soc_dev->dev.groups);
	kfree(soc_dev);
}

int soc_attr_read_machine(struct soc_device_attribute *soc_dev_attr)
{
	if (soc_dev_attr->machine)
		return -EBUSY;

	return of_machine_read_model(&soc_dev_attr->machine);
}

Annotation

Implementation Notes