参考:https://my.oschina.net/felixliang/blog/80960
void __init bcm2708_init(void)
{
...
bcm_register_device(&bcm2708_bsc0_device);
bcm_register_device(&bcm2708_bsc1_device);
...
}
int __init bcm_register_device(struct platform_device *pdev)
{
...
ret = platform_device_register(pdev);
...
}
int platform_device_register(struct platform_device *pdev)
{
...
return platform_device_add(pdev);
}
int platform_device_add(struct platform_device *pdev)
{
...
pdev->dev.bus = &platform_bus_type; //platform设备的总线类型是platform_bus
if (pdev->id != -1) //设置设备名
dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
else
dev_set_name(&pdev->dev, "%s", pdev->name);
for (i = 0; i < pdev->num_resources; i++) { //配置设备资源,非常重要,这里略过
...
}
...
ret = device_add(&pdev->dev);
....
}
int device_add(struct device *dev)
{
struct device *parent = NULL;
struct kobject *kobj;
struct class_interface *class_intf;
int error = -EINVAL;
dev = get_device(dev);
if (!dev)
goto done;
if (!dev->p) {
error = device_private_init(dev);
if (error)
goto done;
}
...
/*在sysfs添加设备目录和属性文件*/
parent = get_device(dev->parent);
kobj = get_device_parent(dev, parent);
if (kobj)
dev->kobj.parent = kobj;
/* use parent numa_node */
if (parent)
set_dev_node(dev, dev_to_node(parent));
/* first, register with generic layer. */
/* we require the name to be set before, and pass NULL */
error = kobject_add(&dev->kobj, dev->kobj.parent, NULL); //建立设备在sysfs下的目录
if (error)
goto Error;
/* notify platform of device entry */
if (platform_notify)
platform_notify(dev);
error = device_create_file(dev, &uevent_attr); //添加uevent属性
if (error)
goto attrError;
if (MAJOR(dev->devt)) {
error = device_create_file(dev, &devt_attr); //添加dev属性
...
}
error = device_add_class_symlinks(dev); //在目录sys/class/ 建立设备连接?
if (error)
goto SymlinkError;
error = device_add_attrs(dev); //添加设备的所属class、type提供的设备属性?
if (error)
goto AttrsError;
error = bus_add_device(dev); //将设备添加到总线中
if (error)
goto BusError;
...
}
int bus_add_device(struct device *dev)
{
struct bus_type *bus = bus_get(dev->bus);
int error = 0;
if (bus) {
pr_debug("bus: '%s': add device %s\n", bus->name, dev_name(dev));
error = device_add_attrs(bus, dev); //添加设备所属bus提供的设备属性
if (error)
goto out_put;
...
klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices); //将设备添加到总线设备链表中
}
return 0;
...
}
/*
* bus->p->klist_devices 是连接 driver和device的桥梁。
*/
补充
关于kobject:object是Linux设备模型的基础结构,其地位类似于面向对象中的基类,通过派生出其他的类来丰富Linux设备模型的结构,如device、kset等。具体方法就是将kobject结构嵌入到上层的数据结构中,这样如果使用了该上层结构,只要访问kboject成员就可以获得kboject结构。
参考:https://www.cnblogs.com/helloahui/p/3677192.html
非常棒的kobject add分析:https://blog.csdn.net/qq_15715753/article/details/104966257