Linux关于总线、设备、驱动的注册顺序
2011-02-20 10:12
381 查看
设备挂接到总线上时,与总线上的所有驱动进行匹配(用bus_type.match进行匹配),
如果匹配成功,则调用bus_type.probe或者driver.probe初始化该设备,挂接到总线上
如果匹配失败,则只是将该设备挂接到总线上。
+----> devices
|
|
|
-----------------------------------------------------------------------------
struct bus_type match() probe()
-----------------------------------------------------------------------------
|
|
|
+----> drivers probe()
驱动挂接到总线上时,与总线上的所有设备进行匹配(用bus_type.match进行匹配),
如果匹配成功,则调用bus_type.probe或者driver.probe初始化该设备;挂接到总线上
如果匹配失败,则只是将该驱动挂接到总线上。
需要重点关注的是总线的匹配函数match(),驱动的初始化函数probe()
1. platform_bus_type--总线先被kenrel注册。
2. 系统初始化过程中调用platform_add_devices或者platform_device_register,将平台设备(platform devices)注册到平台总线中(platform_bus_type)
3. 平台驱动(platform driver)与平台设备(platform device)的关联是在platform_driver_register或者driver_register中实现,一般这个函数在驱动的初始化过程调用。
通过这三步,就将平台总线,设备,驱动关联起来。
1. platform bus先被kenrel注册。
------------------------------------------------------
do_basic_setup() -->-driver_init() -->-platform_bus_init()-->bus_register()
2. 系统初始化过程中调用platform_add_devices或者platform_device_register,将平台设备(platform devices)注册到平台总线中(platform_bus_type)
------------------------------------------------------
系统启动阶段,总线的驱动链表还是空的,所以启动阶段的platform_add_devices()只负责将设备添加到总线的设备链表上。
linux-2.6.26/drivers/base/platform.c
int platform_add_devices(struct platform_device **devs, int num)
{
----...
----ret = platform_device_register(devs[i]);
----...
}
int platform_device_register(struct platform_device *pdev)
{
----device_initialize(&pdev->dev);
----return platform_device_add(pdev);
}
int platform_device_add(struct platform_device *pdev)
{
----...
----pdev->dev.bus = &platform_bus_type;
----...
----ret = device_add(&pdev->dev);
----...
}
device_add() -->-bus_attach_device()
void bus_attach_device(struct device *dev)
{
----struct bus_type *bus = dev->bus;
----int ret = 0;
----if (bus) {
--------if (bus->p->drivers_autoprobe)
------------ret = device_attach(dev);
--------WARN_ON(ret < 0);
--------if (ret >= 0)
------------klist_add_tail(&dev->knode_bus, &bus->p->klist_devices);
----}
}
device_attach()的返回值:
1 设备和驱动匹配成功
0 设备已经注册,但是总线上没有与之相匹配的驱动(系统启动阶段,由于总线上还没有驱动,所以设备在此匹配不到与之对应的驱动,只是将其添加到总线的设备链表)
-ENODEV 设备没有注册(registered) -- 设备在哪里注册?
如果设备和驱动匹配成功;或者设备已经注册,但是总线上没有与之相匹配的驱动,bus_attach_device()将调用klist_add_tail()将设备添加到总线的设备链表尾部。
如果匹配成功,则调用bus_type.probe或者driver.probe初始化该设备,挂接到总线上
如果匹配失败,则只是将该设备挂接到总线上。
+----> devices
|
|
|
-----------------------------------------------------------------------------
struct bus_type match() probe()
-----------------------------------------------------------------------------
|
|
|
+----> drivers probe()
驱动挂接到总线上时,与总线上的所有设备进行匹配(用bus_type.match进行匹配),
如果匹配成功,则调用bus_type.probe或者driver.probe初始化该设备;挂接到总线上
如果匹配失败,则只是将该驱动挂接到总线上。
需要重点关注的是总线的匹配函数match(),驱动的初始化函数probe()
1. platform_bus_type--总线先被kenrel注册。
2. 系统初始化过程中调用platform_add_devices或者platform_device_register,将平台设备(platform devices)注册到平台总线中(platform_bus_type)
3. 平台驱动(platform driver)与平台设备(platform device)的关联是在platform_driver_register或者driver_register中实现,一般这个函数在驱动的初始化过程调用。
通过这三步,就将平台总线,设备,驱动关联起来。
1. platform bus先被kenrel注册。
------------------------------------------------------
do_basic_setup() -->-driver_init() -->-platform_bus_init()-->bus_register()
2. 系统初始化过程中调用platform_add_devices或者platform_device_register,将平台设备(platform devices)注册到平台总线中(platform_bus_type)
------------------------------------------------------
系统启动阶段,总线的驱动链表还是空的,所以启动阶段的platform_add_devices()只负责将设备添加到总线的设备链表上。
linux-2.6.26/drivers/base/platform.c
int platform_add_devices(struct platform_device **devs, int num)
{
----...
----ret = platform_device_register(devs[i]);
----...
}
int platform_device_register(struct platform_device *pdev)
{
----device_initialize(&pdev->dev);
----return platform_device_add(pdev);
}
int platform_device_add(struct platform_device *pdev)
{
----...
----pdev->dev.bus = &platform_bus_type;
----...
----ret = device_add(&pdev->dev);
----...
}
device_add() -->-bus_attach_device()
void bus_attach_device(struct device *dev)
{
----struct bus_type *bus = dev->bus;
----int ret = 0;
----if (bus) {
--------if (bus->p->drivers_autoprobe)
------------ret = device_attach(dev);
--------WARN_ON(ret < 0);
--------if (ret >= 0)
------------klist_add_tail(&dev->knode_bus, &bus->p->klist_devices);
----}
}
device_attach()的返回值:
1 设备和驱动匹配成功
0 设备已经注册,但是总线上没有与之相匹配的驱动(系统启动阶段,由于总线上还没有驱动,所以设备在此匹配不到与之对应的驱动,只是将其添加到总线的设备链表)
-ENODEV 设备没有注册(registered) -- 设备在哪里注册?
如果设备和驱动匹配成功;或者设备已经注册,但是总线上没有与之相匹配的驱动,bus_attach_device()将调用klist_add_tail()将设备添加到总线的设备链表尾部。
相关文章推荐
- Linux关于总线、设备、驱动的注册顺序
- Linux关于总线、设备、驱动的注册顺序
- Linux关于总线、设备、驱动的注册顺序
- Linux关于总线、设备、驱动的注册顺序
- Linux关于总线、设备、驱动的注册顺序
- Linux关于总线、设备、驱动的注册顺序
- 迅为4412开发板Linux驱动教程——总线_设备_驱动注册流程详解
- 迅为Linux驱动教程——总线_设备_驱动注册流程详解
- linux中platform总线解析(四)(platform设备注册后自动匹配驱动)
- linux 下platform设备和驱动注册的先后顺序
- linux总线,设备,驱动注册
- linux iic驱动编程之二 向总线注册设备(2)
- 迅为Linux驱动教程——总线_设备_驱动注册流程详解
- linux 下platform设备和驱动注册的先后顺序
- 迅为4412开发板Linux驱动教程——总线_设备_驱动注册流程详解
- 迅为4412开发板Linux驱动教程——总线_设备_驱动注册流程详解
- 设备驱动----Linux中总线、设备、驱动是如何关联的?
- Linux总线设备驱动模型
- 老查的ARM学习笔记:chapter-2(linux总线设备驱动详解)
- 【Linux开发】linux设备驱动归纳总结(八):2.总线、设备和驱动的关系