美文网首页
platform_device_rigister()过程追踪

platform_device_rigister()过程追踪

作者: 小可_34e0 | 来源:发表于2021-09-15 17:04 被阅读0次

    参考: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

    相关文章

      网友评论

          本文标题:platform_device_rigister()过程追踪

          本文链接:https://www.haomeiwen.com/subject/jihvwltx.html