文件/drivers/base/platform.c

int __init platform_bus_init(void)

{
        int error;

early_platform_cleanup();

error = device_register(&platform_bus);
        if (error)
                return error;
        error =   bus_register(&platform_bus_type);
        if (error)
                device_unregister(&platform_bus);
        return error;

}

该源码在《linux设备:初始化》中已经粘贴过,是和devices_init()一起被driver_init(void)调用的,只不过当时没有深挖

文件/drivers/base/core.c

/**
 * device_add - 添加device到设备层
 * @dev: device.
 *
 * 这是device_register()的第二层, 不过如果device_initialize()已经被
 * 调用过的话,它也可以被单独调用。
 *
 * 这里通过kobject_add()添加@dev到 kobject 层, 添加它到全局和设备的
 * sibling(兄弟) lists,然后把它添加到驱动module的其他相关子系统。
 *
 * 不要为任何device结构调用该方法或device_register()超过一次。该
 * 模型核心不是为那些可以注销掉之后再返回继续使用的设备设计的。
 * (在其他部分,很难保证@dev的所有索引都已经释放了) 应该要分配并
 * 注册一个新的device结构。
 *
 * NOTE: 在调用该方法之后绝对不要直接释放 @dev,即使它返回一个
 * error! 应该使用put_device()来释放其索引。
 */
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;
        }

/*
        * for statically allocated devices, which should all be converted
        * some day, we need to initialize the name. We prevent reading back
        * the name, and force the use of dev_name()
        */
        if (dev->init_name) {
                dev_set_name(dev, "%s", dev->init_name);
                dev->init_name = NULL;
        }

/* subsystems can specify simple device enumeration */
        if (!dev_name(dev) && dev->bus && dev->bus->dev_name)
                dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id);

if (!dev_name(dev)) {
                error = -EINVAL;
                goto name_error;
        }

pr_debug("device: '%s': %s\n", dev_name(dev), __func__);

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);
        if (error)
                goto Error;

/* notify platform of device entry */
        if (platform_notify)
                platform_notify(dev);

error = device_create_file(dev, &dev_attr_uevent);
        if (error)
                goto attrError;

if (MAJOR(dev->devt)) {
                error = device_create_file(dev, &dev_attr_dev);
                if (error)
                        goto ueventattrError;

error = device_create_sys_dev_entry(dev);
                if (error)
                        goto devtattrError;

devtmpfs_create_node(dev);
        }

error = device_add_class_symlinks(dev);
        if (error)
                goto SymlinkError;
        error = device_add_attrs(dev);
        if (error)
                goto AttrsError;
        error = bus_add_device(dev);
        if (error)
                goto BusError;
        error = dpm_sysfs_add(dev);
        if (error)
                goto DPMError;
        device_pm_add(dev);

/* Notify clients of device addition.  该调用必须在dpm_sysfs_add()
        * 之后而在kobject_uevent()之前.
        */
        if (dev->bus)
                blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_ADD_DEVICE, dev);

kobject_uevent(&dev->kobj, KOBJ_ADD);
        bus_probe_device(dev);
        if (parent)
                klist_add_tail(&dev->p->knode_parent, &parent->p->klist_children);

if (dev->class) {
                mutex_lock(&dev->class->p->mutex);
                /* tie the class to the device */
                klist_add_tail(&dev->knode_class, &dev->class->p->klist_devices);

/* notify any interfaces that the device is here */
                list_for_each_entry(class_intf, &dev->class->p->interfaces, node)
                if (class_intf->add_dev)
                        class_intf->add_dev(dev, class_intf);
                mutex_unlock(&dev->class->p->mutex);
        }
        done:
        put_device(dev);
        return error;
DPMError:
        bus_remove_device(dev);
 BusError:
        device_remove_attrs(dev);
 AttrsError:
        device_remove_class_symlinks(dev);
 SymlinkError:
        if (MAJOR(dev->devt))
                devtmpfs_delete_node(dev);
        if (MAJOR(dev->devt))
                device_remove_sys_dev_entry(dev);
devtattrError:
        if (MAJOR(dev->devt))
                device_remove_file(dev, &dev_attr_dev);
ueventattrError:
        device_remove_file(dev, &dev_attr_uevent);
 attrError:
        kobject_uevent(&dev->kobj, KOBJ_REMOVE);
        kobject_del(&dev->kobj);
 Error:
        cleanup_device_parent(dev);
        if (parent)
                put_device(parent);
name_error:
        kfree(dev->p);
        dev->p = NULL;
        goto done;
}

学习《Linux设备模型浅析之设备篇》笔记(二)相关推荐

  1. PyTorch学习笔记(二)——回归

    PyTorch学习笔记(二)--回归 本文主要是用PyTorch来实现一个简单的回归任务. 编辑器:spyder 1.引入相应的包及生成伪数据 import torch import torch.nn ...

  2. MATLAB学习笔记——二维和三维绘图

    MATLAB学习笔记--二维和三维绘图 近期练习matlab的二维和三维绘图,整理一下,以防忘记. 文章目录 MATLAB学习笔记--二维和三维绘图 一.二维绘图 1.plot命令 2.fplot 命 ...

  3. 嵌入式系统设计师学习笔记二十八:嵌入式程序设计③——高级程序设计语言

    嵌入式系统设计师学习笔记二十八:嵌入式程序设计③--高级程序设计语言 解释程序和编译程序 编译器的工作阶段示意图 语法错误:非法字符,关键字或标识符拼写错误 语法错误:语法结构出错,if--endif ...

  4. 计算鬼成像学习笔记二:二阶关联函数探究

    计算鬼成像学习笔记二:二阶关联函数探究 1 一阶关联函数 2 二阶关联函数 3 二阶关联如何重构物体 4 差分鬼成像关联公式 5 归一化鬼成像关联公式 1 一阶关联函数 一阶关联函数是光场的电场强度之 ...

  5. qml学习笔记(二):可视化元素基类Item详解(上半场anchors等等)

    原博主博客地址:http://blog.csdn.net/qq21497936 本文章博客地址:http://blog.csdn.net/qq21497936/article/details/7851 ...

  6. [转载]dorado学习笔记(二)

    原文地址:dorado学习笔记(二)作者:傻掛 ·isFirst, isLast在什么情况下使用?在遍历dataset的时候会用到 ·dorado执行的顺序,首先由jsp发送请求,调用相关的ViewM ...

  7. tensorflow学习笔记二——建立一个简单的神经网络拟合二次函数

    tensorflow学习笔记二--建立一个简单的神经网络 2016-09-23 16:04 2973人阅读 评论(2) 收藏 举报  分类: tensorflow(4)  目录(?)[+] 本笔记目的 ...

  8. Scapy学习笔记二

    Scapy学习笔记二 Scapy Sniffer的用法: http://blog.csdn.net/qwertyupoiuytr/article/details/54670489 Scapy Snif ...

  9. Ethernet/IP 学习笔记二

    Ethernet/IP 学习笔记二 原文链接:http://wiki.mbalib.com/wiki/Ethernet/IP 1.通信模式 不同于源/目的通信模式,EtherNet/IP 采用生产/消 ...

  10. Java学习笔记二:数据类型

    Java学习笔记二:数据类型 1. 整型:没有小数部分,允许为负数,Java整型分4种:int short long byte 1.1 Int最为常用,一个Int类型变量在内存中占用4个字节,取值范围 ...

最新文章

  1. spring包自动扫描声明
  2. MySQL第1天:整体目录
  3. java的方法什么时候加载,java – JVM什么时候加载类?
  4. java swt 菜鸟教程_编程基础学习JS的入门教程
  5. Axios实现异步通信
  6. 模糊搜索怎么实现_干货 | 你真的了解自己是怎么搜索的吗_01
  7. webdriver 的三种等待方式
  8. 互联网日报 | 微信支付启动“8.8智慧生活日”;抖音企业号数量突破400万;苏宁将布局车联网领域...
  9. java设计与模式_设计模式《JAVA与模式》之状态模式
  10. 个人电脑 公司电脑 代理_你们想要打造的树莓派电脑,刚发布了官方版:性能更强大,只卖70美元...
  11. java volatile 原子性_Java并发编程之验证volatile不能保证原子性
  12. 《番茄工作法图解》一次只做一件事
  13. Go 爱好者福利,《Go 语言编程之旅》正式开源!
  14. 订单可视化2实战-生产交付流程(流程再造核心区)
  15. 从身份证号获取身份证信息
  16. 上岸重庆邮电大学软件工程学院学硕总结
  17. 如何给图片加水印,图片加水印怎么加
  18. iphone手机音频AAC视频H264推流(一) iphone手机推流最佳方案
  19. Linux学习入门-------------------------VMvare与镜像的安装与配置
  20. c语言魔王语言上机报告,魔王语言报告(带有完整程序).doc

热门文章

  1. C++ 向量(vector) 的使用
  2. Android 多渠道打包
  3. 《小团团团队》第五次作业:项目需求分析改进与系统设计
  4. .Net Core快速创建Windows服务
  5. 图形数据库Neo4j基本了解
  6. 五:Angular 数据绑定 (Data Binding)
  7. 怎么理解ASM中的Failgroup
  8. Eclipse使用Maven建立SSM多模块的项目
  9. 《人件集》阅读笔记第一篇
  10. 机器学习入门(14)— 神经网络学习整体流程、误差反向传播代码实现、误差反向传播梯度确认、误差反向传播使用示例