您的位置:首页 > 其它

platform总线注册过程及platform_driver与platform_device的匹配

2013-03-29 18:12 351 查看
我们知道,按platform结构写驱动,我们只需注册platform_device和platform_driver而不需要我们自己去注册platform总线,因为系统启动就有那条总线,那么它是怎么得到的呢?这里进行具体跟踪一下:

start_kernel——>rest_init——>kernel_thread(这个线程创建很重要)——>kernel_init——>do_basic_setup——>driver_init——>platform_bus_init

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;

}

根据platform_bus_type总线类型得

struct bus_type platform_bus_type = {

.name = "platform",

.dev_attrs = platform_dev_attrs,

.match = platform_match,//永远记住总线的match函数才是最终的设备与驱动的匹配函数,成功后会调用驱动的probe函数

.uevent = platform_uevent,

.pm = &platform_dev_pm_ops,

};

这里继续分析匹配过程:

platform_driver_register——>driver_register——>bus_add_driver——>driver_attach——>bus_for_each_dev——>__driver_attach——>driver_match_device——>drv->bus->match——>(*match)(struct device *dev, struct device_driver *drv);

这里找到总线类型中的match函数,这里只是个函数指针,很明显platform_bus_type结构下有具体match的实现,匹配后会自动调用驱动下的probe函数

struct bus_type {

const char *name;

struct bus_attribute *bus_attrs;

struct device_attribute *dev_attrs;

struct driver_attribute *drv_attrs;

do_basic_setup

int (*match)(struct device *dev, struct device_driver *drv);

int (*uevent)(struct device *dev, struct kobj_uevent_env *env);

int (*probe)(struct device *dev);

int (*remove)(struct device *dev);

void (*shutdown)(struct device *dev);

int (*suspend)(struct device *dev, pm_message_t state);

int (*resume)(struct device *dev);

const struct dev_pm_ops *pm;

struct bus_type_private *p;

};

static int platform_match(struct device *dev, struct device_driver *drv)//platform_bustype匹配函数

{

struct platform_device *pdev = to_platform_device(dev);

struct platform_driver *pdrv = to_platform_driver(drv);

/* match against the id table first */

if (pdrv->id_table)

return platform_match_id(pdrv->id_table, pdev) != NULL;

/* fall-back to driver name match */

return (strcmp(pdev->name, drv->name) == 0);

}

接下来看driver的probe函数是如何被调用的:

platform_driver_register——>driver_register——>bus_add_driver——>driver_attach——>bus_for_each_dev——>__driver_attach——>driver_probe_device——>really_probe——>drv->probe——>int (*probe) (struct device *dev)(这个函数指针就指向我们真正填写的device+driver下的probe)
注意:总线、设备、驱动结构中,总线的match函数负责匹配驱动与设备;然后匹配成功后会调用驱动中的probe函数,卸载驱动或设备的时候后调用release函数

同样对于platform_device_register中也会去调用bus中的match

platform_device_register——>platform_device_add——>device_add——>bus_probe_device-------->device_attach——>bus_for_each_drv——>__device_attach——>driver_match_device——>bus->match----->driver_probe_device---->really_probe----->bus->probe---->drv->probe——>int
(*probe) (struct device *dev)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: