700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > platform总线注册过程及platform_driver与platform_device的匹配

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

时间:2019-01-31 15:31:16

相关推荐

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

我们知道,按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函数

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。