Linux关于总线、设备、驱动的注册顺序

Linux 关于总线、设备、驱动的注册顺序

        设备 挂接到总线上时,与总线上的所有驱动 进行匹配(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() 将设备添加到总线的设备链表尾部。

你可能感兴趣的:(linux,struct,basic,平台)