static int vduse_init()

in vdpa_user/vduse_dev.c [1588:1656]


static int vduse_init(void)
{
	int ret;
	struct device *dev;

	vduse_class = class_create(THIS_MODULE, "vduse");
	if (IS_ERR(vduse_class))
		return PTR_ERR(vduse_class);

	vduse_class->devnode = vduse_devnode;
	vduse_class->dev_groups = vduse_dev_groups;

	ret = alloc_chrdev_region(&vduse_major, 0, VDUSE_DEV_MAX, "vduse");
	if (ret)
		goto err_chardev_region;

	/* /dev/vduse/control */
	cdev_init(&vduse_ctrl_cdev, &vduse_ctrl_fops);
	vduse_ctrl_cdev.owner = THIS_MODULE;
	ret = cdev_add(&vduse_ctrl_cdev, vduse_major, 1);
	if (ret)
		goto err_ctrl_cdev;

	dev = device_create(vduse_class, NULL, vduse_major, NULL, "control");
	if (IS_ERR(dev)) {
		ret = PTR_ERR(dev);
		goto err_device;
	}

	/* /dev/vduse/$DEVICE */
	cdev_init(&vduse_cdev, &vduse_dev_fops);
	vduse_cdev.owner = THIS_MODULE;
	ret = cdev_add(&vduse_cdev, MKDEV(MAJOR(vduse_major), 1),
		       VDUSE_DEV_MAX - 1);
	if (ret)
		goto err_cdev;

	vduse_irq_wq = alloc_workqueue("vduse-irq",
				WQ_HIGHPRI | WQ_SYSFS | WQ_UNBOUND, 0);
	if (!vduse_irq_wq) {
		ret = -ENOMEM;
		goto err_wq;
	}

	ret = vduse_domain_init();
	if (ret)
		goto err_domain;

	ret = vduse_mgmtdev_init();
	if (ret)
		goto err_mgmtdev;

	return 0;
err_mgmtdev:
	vduse_domain_exit();
err_domain:
	destroy_workqueue(vduse_irq_wq);
err_wq:
	cdev_del(&vduse_cdev);
err_cdev:
	device_destroy(vduse_class, vduse_major);
err_device:
	cdev_del(&vduse_ctrl_cdev);
err_ctrl_cdev:
	unregister_chrdev_region(vduse_major, VDUSE_DEV_MAX);
err_chardev_region:
	class_destroy(vduse_class);
	return ret;
}