您的位置:首页 > 其它

platform的probe函数是何时被调用的

2010-10-14 20:31 127 查看
这几天搞TI的vpfe,里面设备的注册使用platform,平台设备注册方式来注册的。一直都知道

112 struct device_driver {
113     const char      * name;
114     struct bus_type     * bus;
115
116     struct completion   unloaded;
117     struct kobject      kobj;
118     struct klist        klist_devices;
119     struct klist_node   knode_bus;
120
121     struct module       * owner;
122
123     int (*probe)    (struct device * dev);
124     int (*remove)   (struct device * dev);
125     void    (*shutdown) (struct device * dev);
126     int (*suspend)  (struct device * dev, pm_message_t state);
127     int (*resume)   (struct device * dev);
128 };


里的probe函数,但是不知道是何时被调用的。经过跟踪代码,在module_init(vpfe_init);模块初始化的时候,vpfe_init函数中调用了

4775     /* Register driver to the kernel */
4776     err = driver_register(&vpfe_driver);


这里

err = driver_register(&vpfe_driver);

的原型为:

171 int driver_register(struct device_driver * drv)
172 {
173     if ((drv->bus->probe && drv->probe) ||
174         (drv->bus->remove && drv->remove) ||
175         (drv->bus->shutdown && drv->shutdown)) {
176         printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods/n", drv->name);
177     }
178     klist_init(&drv->klist_devices, klist_devices_get, klist_devices_put);
179     init_completion(&drv->unloaded);
180     return bus_add_driver(drv);
181 }


跟踪bus_add_driver(drv);得到bus_add_driver(struct device_driver * drv)的原型:

479 int bus_add_driver(struct device_driver * drv)
480 {
481     struct bus_type * bus = get_bus(drv->bus);
482     int error = 0;
483
484     if (bus) {
485         pr_debug("bus %s: add driver %s/n", bus->name, drv->name);
486         error = kobject_set_name(&drv->kobj, "%s", drv->name);
487         if (error) {
488             put_bus(bus);
489             return error;
490         }
491         drv->kobj.kset = &bus->drivers;
492         if ((error = kobject_register(&drv->kobj))) {
493             put_bus(bus);
494             return error;
495         }
496
497         driver_attach(drv);
498         klist_add_tail(&drv->knode_bus, &bus->klist_drivers);
499         module_add_driver(drv->owner, drv);
500
501         driver_add_attrs(bus, drv);
502         add_bind_files(drv);
503     }
504     return error;
505 }

其中190 void driver_attach(struct device_driver * drv)
191 {
192     bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
193 }

__driver_attach是一个函数,原型:

155 static int __driver_attach(struct device * dev, void * data)
156 {
157     struct device_driver * drv = data;
158
159     /*
160      * Lock device and try to bind to it. We drop the error
161      * here and always return 0, because we need to keep trying
162      * to bind to devices and some drivers will return an error
163      * simply if it didn't support the device.
164      *
165      * driver_probe_device() will spit a warning if there
166      * is an error.
167      */
168
169     if (dev->parent)    /* Needed for USB */
170         down(&dev->parent->sem);
171     down(&dev->sem);
172     if (!dev->driver)
173         driver_probe_device(drv, dev);
174     up(&dev->sem);
175     if (dev->parent)
176         up(&dev->parent->sem);
177
178     return 0;
179 }


这里调用了 driver_probe_device(drv, dev);

原型:

76 int driver_probe_device(struct device_driver * drv, struct device * dev)
77 {
78     int ret = 0;
79
80     if (drv->bus->match && !drv->bus->match(dev, drv))
81         goto Done;
82
83     pr_debug("%s: Matched Device %s with Driver %s/n",
84          drv->bus->name, dev->bus_id, drv->name);
85     dev->driver = drv;
86     if (dev->bus->probe) {
87         ret = dev->bus->probe(dev);
88         if (ret) {
89             dev->driver = NULL;
90             goto ProbeFailed;
91         }
92     } else if (drv->probe) {
93         ret = drv->probe(dev);
94         if (ret) {
95             dev->driver = NULL;
96             goto ProbeFailed;
97         }
98     }
99     device_bind_driver(dev);
100     ret = 1;
101     pr_debug("%s: Bound Device %s to Driver %s/n",
102          drv->bus->name, dev->bus_id, drv->name);
103     goto Done;
104
105  ProbeFailed:
106     if (ret == -ENODEV || ret == -ENXIO) {
107         /* Driver matched, but didn't support device
108          * or device not found.
109          * Not an error; keep going.
110          */
111         ret = 0;
112     } else {
113         /* driver matched but the probe failed */
114         printk(KERN_WARNING
115                "%s: probe of %s failed with error %d/n",
116                drv->name, dev->bus_id, ret);
117     }
118  Done:
119     return ret;
120 }


可以看出是先调用了总线的probe方法,接着调用了设备的probe方法。

总之一句话,probe函数作为driver的最基本的函数指针,一旦你的device和driver匹配(match,由总线(bus)来完成,匹配工作发生在device_register()和drvier_register()

的时候),probe函数就肯定会被调用,期间一般会完成device的初始化,注册中断等操作。

顺便讲下在内核中是怎么按照driver mode来实现整个系统的设备和驱动注册的。

在系统初始化阶段,会首先向内核注册各种常用的总线类型,比如pci, usb, spi, i2c, platform等等,当然你也可以自己发明一种总线类型注册上去。

这部分代码一般放在./arch/arm/mach-xxx/board-xxx.c中。

在此之后,会将系统的设备列表,基本上整个系统的device都在这里了,一一地注册进内核,就是调用device_regisger注册的过程。然后是对于各个device设备driver的注册。

这部分代码一般放在./drvier/下面。

大部分device和driver的匹配方式就是看名字是否相同,这部分属于总线分内的事情。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: