in most_cdev.c [412:476]
static int comp_probe(struct most_interface *iface, int channel_id,
struct most_channel_config *cfg, char *name, char *args)
{
struct comp_channel *c;
unsigned long cl_flags;
int retval;
int current_minor;
if (!cfg || !name)
return -EINVAL;
c = get_channel(iface, channel_id);
if (c)
return -EEXIST;
current_minor = ida_simple_get(&comp.minor_id, 0, 0, GFP_KERNEL);
if (current_minor < 0)
return current_minor;
c = kzalloc(sizeof(*c), GFP_KERNEL);
if (!c) {
retval = -ENOMEM;
goto err_remove_ida;
}
c->devno = MKDEV(comp.major, current_minor);
cdev_init(&c->cdev, &channel_fops);
c->cdev.owner = THIS_MODULE;
retval = cdev_add(&c->cdev, c->devno, 1);
if (retval < 0)
goto err_free_c;
c->iface = iface;
c->cfg = cfg;
c->channel_id = channel_id;
c->access_ref = 0;
spin_lock_init(&c->unlink);
INIT_KFIFO(c->fifo);
retval = kfifo_alloc(&c->fifo, cfg->num_buffers, GFP_KERNEL);
if (retval)
goto err_del_cdev_and_free_channel;
init_waitqueue_head(&c->wq);
mutex_init(&c->io_mutex);
spin_lock_irqsave(&ch_list_lock, cl_flags);
list_add_tail(&c->list, &channel_list);
spin_unlock_irqrestore(&ch_list_lock, cl_flags);
c->dev = device_create(comp.class, NULL, c->devno, NULL, "%s", name);
if (IS_ERR(c->dev)) {
retval = PTR_ERR(c->dev);
goto err_free_kfifo_and_del_list;
}
kobject_uevent(&c->dev->kobj, KOBJ_ADD);
return 0;
err_free_kfifo_and_del_list:
kfifo_free(&c->fifo);
list_del(&c->list);
err_del_cdev_and_free_channel:
cdev_del(&c->cdev);
err_free_c:
kfree(c);
err_remove_ida:
ida_simple_remove(&comp.minor_id, current_minor);
return retval;
}