在前面有一篇文章linux驱动相关知识整理中我们提到,总线是关联驱动和设备的枢纽,那么在分析EMMC驱动的时候,我们先来分析总线。
而通过前一篇文章emmc驱动代码预览可以知道在core文件夹下有bus.h/.c文件,那就进去瞧一瞧吧。
打开bus.c文件,下面有这样一段代码:
subsys_initcall(mmc_init);
module_exit(mmc_exit);
subsys_initcall也是一个类似模块加载module_init的宏,而且subsys_initcall比module_init要先执行,这里只需要知道它是用来向内核注册一个什么就好了。
再来看看mmc_init
static int __init mmc_init(void)
{
int ret;
workqueue = alloc_ordered_workqueue("kmmcd", 0);
if (!workqueue)
return -ENOMEM;
ret = mmc_register_bus();
if (ret)
goto destroy_workqueue;
ret = mmc_register_host_class();
if (ret)
goto unregister_bus;
ret = sdio_register_bus();
if (ret)
goto unregister_host_class;
return 0;
unregister_host_class:
mmc_unregister_host_class();
unregister_bus:
mmc_unregister_bus();
destroy_workqueue:
destroy_workqueue(workqueue);
return ret;
}
该代码段中,mmc_register_bus函数被调用了,再扒进去看一下:
int mmc_register_bus(void)
{
return bus_register(&mmc_bus_type);
}
著名的总线注册内核函数bus_register在这里被调用。
其中mmc_bus_type变量定义如下:
static struct bus_type mmc_bus_type = {
.name = "mmc",
.dev_groups = mmc_dev_groups,
.match = mmc_bus_match,
.uevent = mmc_bus_uevent,
.probe = mmc_bus_probe,
.remove = mmc_bus_remove,
.shutdown = mmc_bus_shutdown,
.pm = &mmc_bus_pm_ops,
};
这里我们看一下,驱动和设备的配对函数
static int mmc_bus_match(struct device *dev, struct device_driver *drv)
{
return 1;
}
固定返回1,表示只要是注册在该总线上的驱动和设备,在match中都匹配成功。
关于emmc驱动请听下回分解。