drivers/accel/habanalabs/common/device.c

Source file repositories/reference/linux-study-clean/drivers/accel/habanalabs/common/device.c

File Facts

System
Linux kernel
Corpus path
drivers/accel/habanalabs/common/device.c
Extension
.c
Size
83762 bytes
Lines
2966
Domain
Driver Families
Bucket
drivers/accel
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 hl_ctrl_ops = {
	.owner = THIS_MODULE,
	.open = hl_device_open_ctrl,
	.release = hl_device_release_ctrl,
	.unlocked_ioctl = hl_ioctl_control,
	.compat_ioctl = hl_ioctl_control
};

static void device_release_func(struct device *dev)
{
	kfree(dev);
}

/*
 * device_init_cdev - Initialize cdev and device for habanalabs device
 *
 * @hdev: pointer to habanalabs device structure
 * @class: pointer to the class object of the device
 * @minor: minor number of the specific device
 * @fops: file operations to install for this device
 * @name: name of the device as it will appear in the filesystem
 * @cdev: pointer to the char device object that will be initialized
 * @dev: pointer to the device object that will be initialized
 *
 * Initialize a cdev and a Linux device for habanalabs's device.
 */
static int device_init_cdev(struct hl_device *hdev, const struct class *class,
				int minor, const struct file_operations *fops,
				char *name, struct cdev *cdev,
				struct device **dev)
{
	cdev_init(cdev, fops);
	cdev->owner = THIS_MODULE;

	*dev = kzalloc_obj(**dev);
	if (!*dev)
		return -ENOMEM;

	device_initialize(*dev);
	(*dev)->devt = MKDEV(hdev->major, minor);
	(*dev)->class = class;
	(*dev)->release = device_release_func;
	dev_set_drvdata(*dev, hdev);
	dev_set_name(*dev, "%s", name);

	return 0;
}

static int cdev_sysfs_debugfs_add(struct hl_device *hdev)
{
	const struct class *accel_class = hdev->drm.accel->kdev->class;
	char name[32];
	int rc;

	hdev->cdev_idx = hdev->drm.accel->index;

	/* Initialize cdev and device structures for the control device */
	snprintf(name, sizeof(name), "accel_controlD%d", hdev->cdev_idx);
	rc = device_init_cdev(hdev, accel_class, hdev->cdev_idx, &hl_ctrl_ops, name,
				&hdev->cdev_ctrl, &hdev->dev_ctrl);
	if (rc)
		return rc;

	rc = cdev_device_add(&hdev->cdev_ctrl, hdev->dev_ctrl);
	if (rc) {
		dev_err(hdev->dev_ctrl,
			"failed to add an accel control char device to the system\n");
		goto free_ctrl_device;
	}

	rc = hl_sysfs_init(hdev);
	if (rc) {
		dev_err(hdev->dev, "failed to initialize sysfs\n");
		goto delete_ctrl_cdev_device;
	}

	hl_debugfs_add_device(hdev);

	hdev->cdev_sysfs_debugfs_created = true;

	return 0;

delete_ctrl_cdev_device:
	cdev_device_del(&hdev->cdev_ctrl, hdev->dev_ctrl);
free_ctrl_device:
	put_device(hdev->dev_ctrl);
	return rc;
}

static void cdev_sysfs_debugfs_remove(struct hl_device *hdev)

Annotation

Implementation Notes