of_register_driver函数

glacierful 2010-04-12 11:24:56
在看i2c总线驱动i2c-cpm.c文件时,初始化的时候,调用of_register_platform_driver(&cpm_i2c_driver),cpm_i2c_driver定义如下:

static struct of_platform_driver cpm_i2c_driver = {
.match_table = cpm_i2c_match,
.probe = cpm_i2c_probe,
.remove = __devexit_p(cpm_i2c_remove),
.driver = {
.name = "fsl-i2c-cpm",
.owner = THIS_MODULE,
}
};

of_register_platform_driver会继续调用of_register_driver,查看of_register_driver的代码,会继续调用driver_register。

调用过程是of_register_platform_driver ->of_register_driver -> driver_register.
我感到奇怪的是,driver_register的输入参数是cpm_i2c_driver的driver成员,也就是说,cpm_i2c_driver中的probe函数指针指向的cpm_i2c_probe没有被调用。

我想知道的是cpm_i2c_probe什么时候会被调用。
...全文
103 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
ghostwcy 2010-04-17
  • 打赏
  • 举报
回复
内核提供了宏to_of_platform_driver,可以通过driver的地址算出cpm_i2c_driver的地址。
查了下,使用宏to_of_platform_driver且访问probe的函数只有一个of_platform_device_probe()
of_platform_device_probe在函数of_bus_type_init()中被使用
函数of_bus_type_init()没找到使用的地方

目前只查到这点
至少可以告诉你,可以通过结构体的成员变量的地址计算出结构体的地址,内核经常干这种事。
driver_register虽然接受的是结构体的成员变量,但是不等于说就无法访问回调函数probe了。
帅得不敢出门 2010-04-17
  • 打赏
  • 举报
回复


//调用的层次比较多 就不贴全代码了 怎么调到really_probe 自己查吧
static int really_probe(struct device *dev, struct device_driver *drv)//从这里开始
{
if (dev->bus->probe) {
ret = dev->bus->probe(dev);
if (ret)
goto probe_failed;
} else if (drv->probe) {
ret = drv->probe(dev);
if (ret)
goto probe_failed;
}
}

-------------------------
int of_bus_type_init(struct bus_type *bus, const char *name)
{
bus->name = name;
bus->match = of_platform_bus_match;
bus->probe = of_platform_device_probe;
bus->remove = of_platform_device_remove;
bus->shutdown = of_platform_device_shutdown;
bus->dev_attrs = of_platform_device_attrs;
bus->pm = OF_PLATFORM_PM_OPS_PTR;
return bus_register(bus);
}
----------------------------------
static int of_platform_device_probe(struct device *dev)
{
int error = -ENODEV;
struct of_platform_driver *drv;
struct of_device *of_dev;
const struct of_device_id *match;

drv = to_of_platform_driver(dev->driver);//这里得到of_platform_driver
of_dev = to_of_device(dev);

if (!drv->probe)
return error;

of_dev_get(of_dev);

match = of_match_device(drv->match_table, of_dev);
if (match)
error = drv->probe(of_dev, match);//这里probe调用
if (error)
of_dev_put(of_dev);

return error;
}
steptodream 2010-04-15
  • 打赏
  • 举报
回复

上网找找资料吧 消灭0回复

4,438

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧