alloc_chrdev_region 原型如下,该函数向内核申请一个空闲的主设备号。
alloc_chrdev_region(&g_aputriger_dev, 0, APUTRIGER_MAX_NUM, "aputriger0");
第四个参数是我们使用cat /proc/devices 看到的名称

/**
 * alloc_chrdev_region() - register a range of char device numbers
 * @dev: output parameter for first assigned number
 * @baseminor: first of the requested range of minor numbers
 * @count: the number of minor numbers required
 * @name: the name of the associated device or driver
 *
 * Allocates a range of char device numbers.  The major number will be
 * chosen dynamically, and returned (along with the first minor number)
 * in @dev.  Returns zero or a negative error code.
 */
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,
			const char *name)
{
	struct char_device_struct *cd;
	cd = __register_chrdev_region(0, baseminor, count, name);
	if (IS_ERR(cd))
		return PTR_ERR(cd);
	*dev = MKDEV(cd->major, cd->baseminor);
	return 0;
}如果我们的设备不止一个,次设备号我们也希望是自动申请而不是人为指定的,那么可以使用ida_simple_get来申请,原型如下:
minor = ida_simple_get(&g_aputriger_dev, 0, APUTRIGER_MAX_NUM, GFP_KERNEL);
#define ida_simple_get(ida, start, end, gfp)	\
			ida_alloc_range(ida, start, (end) - 1, gfp)
/**
 * ida_alloc_range() - Allocate an unused ID.
 * @ida: IDA handle.
 * @min: Lowest ID to allocate.
 * @max: Highest ID to allocate.
 * @gfp: Memory allocation flags.
 *
 * Allocate an ID between @min and @max, inclusive.  The allocated ID will
 * not exceed %INT_MAX, even if @max is larger.
 *
 * Context: Any context.
 * Return: The allocated ID, or %-ENOMEM if memory could not be allocated,
 * or %-ENOSPC if there are no free IDs.
 */
int ida_alloc_range(struct ida *ida, unsigned int min, unsigned int max,
			gfp_t gfp)
{
	int id = 0;
	unsigned long flags;
	if ((int)min < 0)
		return -ENOSPC;
	if ((int)max < 0)
		max = INT_MAX;
again:
	xa_lock_irqsave(&ida->ida_rt, flags);
	id = ida_get_new_above(ida, min);
	if (id > (int)max) {
		ida_remove(ida, id);
		id = -ENOSPC;
	}
	xa_unlock_irqrestore(&ida->ida_rt, flags);
	if (unlikely(id == -EAGAIN)) {
		if (!ida_pre_get(ida, gfp))
			return -ENOMEM;
		goto again;
	}
	return id;
}创建设备示例:
	if (cdev_add(&cur_dev->cdev, MKDEV(g_aputriger_dev, minor), 1)) {
		pr_err("%s cdev add failed\n", cdev_name);
		goto err_class_destr;
	}
	/* devices create */
	cur_dev->dev = device_create(cur_dev->class, NULL, MKDEV(cur_dev->major, minor), NULL, cdev_name);


















