sysfs之platform总线初始化简单分析

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行是对前面的程序出错后,进行的错误处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值