emmc/sd驱动总线简析

在前面有一篇文章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驱动请听下回分解。





版权声明:本文为dengziliang001原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。