static int hsc_probe()

in clients/hsi_char.c [675:731]


static int hsc_probe(struct device *dev)
{
	const char devname[] = "hsi_char";
	struct hsc_client_data *cl_data;
	struct hsc_channel *channel;
	struct hsi_client *cl = to_hsi_client(dev);
	unsigned int hsc_baseminor;
	dev_t hsc_dev;
	int ret;
	int i;

	cl_data = kzalloc(sizeof(*cl_data), GFP_KERNEL);
	if (!cl_data)
		return -ENOMEM;

	hsc_baseminor = HSC_BASEMINOR(hsi_id(cl), hsi_port_id(cl));
	if (!hsc_major) {
		ret = alloc_chrdev_region(&hsc_dev, hsc_baseminor,
						HSC_DEVS, devname);
		if (ret == 0)
			hsc_major = MAJOR(hsc_dev);
	} else {
		hsc_dev = MKDEV(hsc_major, hsc_baseminor);
		ret = register_chrdev_region(hsc_dev, HSC_DEVS, devname);
	}
	if (ret < 0) {
		dev_err(dev, "Device %s allocation failed %d\n",
					hsc_major ? "minor" : "major", ret);
		goto out1;
	}
	mutex_init(&cl_data->lock);
	hsi_client_set_drvdata(cl, cl_data);
	cdev_init(&cl_data->cdev, &hsc_fops);
	cl_data->cdev.owner = THIS_MODULE;
	cl_data->cl = cl;
	for (i = 0, channel = cl_data->channels; i < HSC_DEVS; i++, channel++) {
		hsc_channel_init(channel);
		channel->ch = i;
		channel->cl = cl;
		channel->cl_data = cl_data;
	}

	/* 1 hsi client -> N char devices (one for each channel) */
	ret = cdev_add(&cl_data->cdev, hsc_dev, HSC_DEVS);
	if (ret) {
		dev_err(dev, "Could not add char device %d\n", ret);
		goto out2;
	}

	return 0;
out2:
	unregister_chrdev_region(hsc_dev, HSC_DEVS);
out1:
	kfree(cl_data);

	return ret;
}