in fsi-scom.c [540:585]
static int scom_probe(struct device *dev)
{
struct fsi_device *fsi_dev = to_fsi_dev(dev);
struct scom_device *scom;
int rc, didx;
scom = kzalloc(sizeof(*scom), GFP_KERNEL);
if (!scom)
return -ENOMEM;
dev_set_drvdata(dev, scom);
mutex_init(&scom->lock);
/* Grab a reference to the device (parent of our cdev), we'll drop it later */
if (!get_device(dev)) {
kfree(scom);
return -ENODEV;
}
scom->fsi_dev = fsi_dev;
/* Create chardev for userspace access */
scom->dev.type = &fsi_cdev_type;
scom->dev.parent = dev;
scom->dev.release = scom_free;
device_initialize(&scom->dev);
/* Allocate a minor in the FSI space */
rc = fsi_get_new_minor(fsi_dev, fsi_dev_scom, &scom->dev.devt, &didx);
if (rc)
goto err;
dev_set_name(&scom->dev, "scom%d", didx);
cdev_init(&scom->cdev, &scom_fops);
rc = cdev_device_add(&scom->cdev, &scom->dev);
if (rc) {
dev_err(dev, "Error %d creating char device %s\n",
rc, dev_name(&scom->dev));
goto err_free_minor;
}
return 0;
err_free_minor:
fsi_free_minor(scom->dev.devt);
err:
put_device(&scom->dev);
return rc;
}