转载地址:http://xl028.blog.163.com/blog/static/199730242201231592010799/
我们知道,按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函数