1.首先看一下device_create函数,注释写的很清楚,创建一个设备,并注册它到sysfs中。提供了强大的格式化注册接口。
/**
-
device_create - creates a device and registers it with sysfs
-
@class: pointer to the struct class that this device should be registered to
-
@parent: pointer to the parent struct device of this new device, if any
-
@devt: the dev_t for the char device to be added
-
@drvdata: the data to be added to the device for callbacks
-
@fmt: string for the device’s name
-
This function can be used by char device classes. A struct device
-
will be created in sysfs, registered to the specified class.
-
A “dev” file will be created, showing the dev_t for the device, if
-
the dev_t is not 0,0.
-
If a pointer to a parent struct device is passed in, the newly created
-
struct device will be a child of that device in sysfs.
-
The pointer to the struct device will be returned from the call.
-
Any further sysfs files that might be required can be created using this
-
pointer.
-
Returns &struct device pointer on success, or ERR_PTR() on error.
-
Note: the struct class passed to this function must have previously
-
been created with a call to class_create().
*/
struct device *device_create(struct class *class, struct device *parent,
dev_t devt, void *drvdata, const char *fmt, …)
{
va_list vargs;
struct device *dev;va_start(vargs, fmt);
dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs);
va_end(vargs);
return dev;
}
2.上面只是为了提供完善的接口,下面这个才是真正干活的。
注释写的也很清楚:
1.创建一个设备(malloc一个device,并填充相关数据)
2.注册这个设备
/**
-
device_create_vargs - creates a device and registers it with sysfs
-
@class: pointer to the struct class that this device should be registered to
-
@parent: pointer to the parent struct device of this new device, if any
-
@devt: the dev_t for the char device to be added
-
@drvdata: the data to be added to the device for callbacks
-
@fmt: string for the device’s name
-
@args: va_list for the device’s name
-
This function can be used by char device classes. A struct device
-
will be created in sysfs, registered to the specified class.
-
A “dev” file will be created, showing the dev_t for the device, if
-
the dev_t is not 0,0.
-
If a pointer to a parent struct device is passed in, the newly created
-
struct device will be a child of that device in sysfs.
-
The pointer to the struct device will be returned from the call.
-
Any further sysfs files that might be required can be created using this
-
pointer.
-
Returns &struct device pointer on success, or ERR_PTR() on error.
-
Note: the struct class passed to this function must have previously
-
been created with a call to class_create().
*/
struct device *device_create_vargs(struct class *class, struct device *parent,
dev_t devt, void *drvdata, const char *fmt,
va_list args)
{
struct device *dev = NULL;
int retval = -ENODEV;if (class == NULL || IS_ERR(class))
goto error;dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev) {
retval = -ENOMEM;
goto error;
}dev->devt = devt;
dev->class = class;
dev->parent = parent;
dev->release = device_create_release;
dev_set_drvdata(dev, drvdata);retval = kobject_set_name_vargs(&dev->kobj, fmt, args);
if (retval)
goto error;retval = device_register(dev);
if (retval)
goto error;return dev;
error:
put_device(dev);
return ERR_PTR(retval);
}
3.真正的注册函数,其实是初始化了一些设备中通用参数(自旋锁,链表等),然后调用device_add就是这里,画重点了
/**
- device_register - register a device with the system.
- @dev: pointer to the device structure
- This happens in two clean steps - initialize the device
- and add it to the system. The two steps can be called
- separately, but this is the easiest and most common.
- I.e. you should only call the two helpers separately if
- have a clearly defined need to use and refcount the device
- before it is added to the hierarchy.
- NOTE: Never directly free @dev after calling this function, even
- if it returned an error! Always use put_device() to give up the
- reference initialized in this function instead.
*/
int device_register(struct device *dev)
{
device_initialize(dev);
return device_add(dev);
}
整体的层次应该是下面这种。
device_create
|
- – kzalloc struct device
|
±–device_register
|
±----device_initialize
|
±----device_add
device_create比device_add多做的事情就非常清楚了。
- 新建struct device, device_add是不会新建的,只会加。
- 进行了初始化, 如果不调device_register, 就得自己去调用device_initiali初始化。