- 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的匹配方式就是看名字是否相同,这部分属于总线分内的事情。