int __init platform_bus_init(void)
{
01 int error;
02
03 early_platform_cleanup();
04
05 error = device_register(&platform_bus);
06 if (error)
07 return error;
08 error = bus_register(&platform_bus_type);
09 if (error)
10 device_unregister(&platform_bus);
11 return error;
12}
第5行使用device_register函数注册platform_bus设备
第8行使用bus_register函数注册一个总线。
第10行如果注册失败,卸载总线。
int device_register(struct device *dev)
{
1 device_initialize(dev);
2 return device_add(dev);
3}
第1行初始化设备
第2行把设备添加到设备层次结构中。
void device_initialize(struct device *dev)
{
01 dev->kobj.kset = devices_kset;
02 kobject_init(&dev->kobj, &device_ktype);
03 INIT_LIST_HEAD(&dev->dma_pools);
04 init_MUTEX(&dev->sem);
05 spin_lock_init(&dev->devres_lock);
06 INIT_LIST_HEAD(&dev->devres_head);
07 device_init_wakeup(dev, 0);
08 device_pm_init(dev);
09 set_dev_node(dev, -1);
10}
第1行设备的kobject对象的kset字段指向全局的kset对象,
第2行初始化设备对象中的kobject对象,并把它加到某个类别中。
第7行设备被初始化和唤醒。
第8行初始化设备的电源状态
第9行初始化设备的节点,指的是内存管理的节点。
int device_add(struct device *dev)
{
001 struct device *parent = NULL;
002 struct class_interface *class_intf;
003 int error = -EINVAL;
004
005 dev = get_device(dev);
006 if (!dev)
007 goto done;
008
009 dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL);
010 if (!dev->p) {
011 error = -ENOMEM;
012 goto done;
013 }
014 dev->p->device = dev;
015 klist_init(&dev->p->klist_children, klist_children_get,
016 klist_children_put);
017
018 /*
019 * for statically allocated devices, which should all be converted
020 * some day, we need to initialize the name. We prevent reading back
021 * the name, and force the use of dev_name()
022 */
023 if (dev->init_name) {
024 dev_set_name(dev, dev->init_name);
025 dev->init_name = NULL;
026 }
027
028 if (!dev_name(dev))
029 goto name_error;
030
031 pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
032
033 parent = get_device(dev->parent);
034 setup_parent(dev, parent);
035
036 /* use parent numa_node */
037 if (parent)
038 set_dev_node(dev, dev_to_node(parent));
039
040 /* first, register with generic layer. */
041 /* we require the name to be set before, and pass NULL */
042 error = kobject_add(&dev->kobj, dev->kobj.parent, NULL);
043 if (error)
044 goto Error;
045
046 /* notify platform of device entry */
047 if (platform_notify)
048 platform_notify(dev);
049
050 error = device_create_file(dev, &uevent_attr);
051 if (error)
052 goto attrError;
053
054 if (MAJOR(dev->devt)) {
055 error = device_create_file(dev, &devt_attr);
056 if (error)
057 goto ueventattrError;
058
059 error = device_create_sys_dev_entry(dev);
060 if (error)
061 goto devtattrError;
062 }
063
064 error = device_add_class_symlinks(dev);
065 if (error)
066 goto SymlinkError;
067 error = device_add_attrs(dev);
068 if (error)
069 goto AttrsError;
070 error = bus_add_device(dev);
071 if (error)
072 goto BusError;
073 error = dpm_sysfs_add(dev);
074 if (error)
075 goto DPMError;
076 device_pm_add(dev);
077
078 /* Notify clients of device addition. This call must come
079 * after dpm_sysf_add() and before kobject_uevent().
080 */
081 if (dev->bus)
082 blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
083 BUS_NOTIFY_ADD_DEVICE, dev);
084
085 kobject_uevent(&dev->kobj, KOBJ_ADD);
086 bus_attach_device(dev);
087 if (parent)
088 klist_add_tail(&dev->p->knode_parent,
089 &parent->p->klist_children);
090
091 if (dev->class) {
092 mutex_lock(&dev->class->p->class_mutex);
093 /* tie the class to the device */
094 klist_add_tail(&dev->knode_class,
095 &dev->class->p->class_devices);
096
097 /* notify any interfaces that the device is here */
098 list_for_each_entry(class_intf,
099 &dev->class->p->class_interfaces, node)
100 if (class_intf->add_dev)
101 class_intf->add_dev(dev, class_intf);
102 mutex_unlock(&dev->class->p->class_mutex);
103 }
104done:
105 put_device(dev);
106 return error;
107 DPMError:
108 bus_remove_device(dev);
109 BusError:
110 device_remove_attrs(dev);
111 AttrsError:
112 device_remove_class_symlinks(dev);
113 SymlinkError:
114 if (MAJOR(dev->devt))
115 device_remove_sys_dev_entry(dev);
116 devtattrError:
117 if (MAJOR(dev->devt))
118 device_remove_file(dev, &devt_attr);
119 ueventattrError:
120 device_remove_file(dev, &uevent_attr);
121 attrError:
122 kobject_uevent(&dev->kobj, KOBJ_REMOVE);
123 kobject_del(&dev->kobj);
124 Error:
125 cleanup_device_parent(dev);
126 if (parent)
127 put_device(parent);
128name_error:
129 kfree(dev->p);
130 dev->p = NULL;
131 goto done;
132}
第5行使用get_device函数来增加对设备的引用,其实get_device函数是kobject_get函数的封装。
第9行对设备的私有指针进行分配空间。
第14行设备的私有指针的设备对象指向目录的设备对象
第15行初始化设备的的链表。
第23行如果设备的名字为真
第24-25行设置设备的名字,然后设置为空。
第28行使用dev_name函数找到设备的名字,其实也是通过kobject_name来返回设备的名字,如果没有这个名字,刚跳转到错误地方,处理。
第33行增加到设备的父设备的引用,其实是增加对kobject父对象的引用。
第34行使这个设备和父设备连接起来。通过get_device_parent这个函数返回设备的父kobject对象。
第42行把设备的kobject对象,加到kobject层次结构中。
第50行创建设备的属性文件,属性为uenevt_attr结构体类型。
第55行创建设备的属性文件,属性为devt_attr结构体类型
第59行创建设备的链接文件。
第64行增加设备类的链接文件。
第67行增加设备的属性,比如设备的类别属性,组属性等
第70行增加到设备到总线上,创建链接到设备的总线。
第76行添加一个设备到一个活动设备列表中。
第81行如果设备被添加到总线中
第82行会把设备添加到通知链中
第85行通知用户空间。
第86行添加设备到总线链表中,试着找到它的驱动。
第87行如果父设备为真,把它加到列表的末尾。
第91行如果设备的类为真,也把它加到列表的末尾。
第114-131行是对前面的程序出错后,进行的错误处理。