linux的emmc驅動在drivers\mmc\card\block.c,其mmc_dirver結構體如下:
- static struct mmc_driver mmc_driver = {
- .drv= {
- .name = "mmcblk",
- },
- .probe = mmc_blk_probe,
- .remove = mmc_blk_remove,
- .suspend = mmc_blk_suspend,
- .resume = mmc_blk_resume,
- };
根據以往平臺總線驅動模型的經驗來看的話,內核裏應該有mmc_devices結構體,並且
其name也爲"mmcblk",這樣其probe函數將被調用,但是搜索整個內核文件並沒有發現mmc_devices。
現在我們分析一下mmc_blk_probe什麼時候被調用。
static int __init mmc_blk_init(void) //drivers\mmc\card\block.c
{
res = mmc_register_driver(&mmc_driver); //註冊mmc_driver
}
int mmc_register_driver(struct mmc_driver *drv) //drivers\mmc\core\bus.c
{
drv->drv.bus = &mmc_bus_type; //mmc設備是掛載在mmc總線上的
return driver_register(&drv->drv); //註冊mmc驅動
}
int driver_register(struct device_driver *drv) //drivers\base\driver.c
{
other = driver_find(drv->name, drv->bus); //在總線上查找是否已經註冊過此驅動
if (other) {
put_driver(other);
printk(KERN_ERR "Error: Driver '%s' is already registered, "
"aborting...\n", drv->name);
return -EBUSY;
}
ret = bus_add_driver(drv); //如果沒有註冊過,則註冊此驅動
}
int bus_add_driver(struct device_driver *drv) //drivers\base\bus.c
{
error = driver_attach(drv);
error = driver_create_file(drv, &driver_attr_uevent);
}
//try to bind driver to devices
int driver_attach(struct device_driver *drv) //drivers/base/dd.c
{
return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
//__driver_attach的裏面device的查找還沒搞清楚
}
static int __driver_attach(struct device *dev, void *data) //drivers/base/dd.c
{
if (!driver_match_device(drv, dev))
return 0;
driver_probe_device(drv, dev);
}
static inline int driver_match_device(struct device_driver *drv, //drivers/base/base.h
struct device *dev)
{
//這裏調用了mmc總線的match函數
return drv->bus->match ? drv->bus->match(dev, drv) : 1;
}
static int mmc_bus_match(struct device *dev, struct device_driver *drv) //drivers\mmc\core\bus.c
{
//mmc總線的match直接返回了1
return 1;
}
int driver_probe_device(struct device_driver *drv, struct device *dev) //drivers/base/dd.c
{
really_probe(dev, drv);
}
static int really_probe(struct device *dev, struct device_driver *drv) //drivers/base/dd.c
{
dev->bus->probe(dev); //這裏調用總線的probe函數
}
static int mmc_bus_probe(struct device *dev) //drivers\mmc\core\bus.c
{
return drv->probe(card); //最終mmc總線的probe函數調用mmc_driver的probe函數
}