448 if (drv->remove)
449 drv->driver.remove = platform_drv_remove;
450 if (drv->shutdown)
451 drv->driver.shutdown = platform_drv_shutdown;
452 if (drv->suspend)
453 drv->driver.suspend = platform_drv_suspend;
454 if (drv->resume)
455 drv->driver.resume = platform_drv_resume;
456 return driver_register(&drv->driver);
457}
458EXPORT_SYMBOL_GPL(platform_driver_register);
不要被上面的platform_drv_XXX吓倒了,它们其实很简单,就是将struct device转换为struct platform_device和struct platform_driver,然后调用platform_driver中的相应接口函数。那为什么不直接调用platform_drv_XXX等接口 呢?这就是Linux内核中面向对象的设计思想。
device_driver提供了一些操作接口,但其并没有实现,相当于一些虚函数,由派生类platform_driver进行重载,无论何种类型的 driver都是基于device_driver派生而来的,device_driver中具体的各种操作都是基于统一的基类接口的,这样就实现了面向对 象的设计。
在文件中,实现了driver_register()函数。
209/**
210 * driver_register - register driver with bus
211 * @drv: driver to register
212 *
213 * We pass off most of the work to the bus_add_driver() call,
214 * since most of the things we have to do deal with the bus
215 * structures.
216 */
217int driver_register(struct device_driver *drv)
218{
219 int ret;
220
//如果总线的方法和设备自己的方法同时存在,将打印告警信息,对于platform bus,其没有probe等接口
221 if ((drv->bus->probe && drv->probe) ||
222 (drv->bus->remove && drv->remove) ||
223 (drv->bus->shutdown && drv->shutdown))
224 printk(KERN_WARNING "Driver \'%s\' needs updating - please use "
225 "bus_type methods/n", drv->name);
//将驱动挂接到总线上,通过总线来驱动设备。
226 ret = bus_add_driver(drv);
227 if (ret)
228 return ret;
229 ret = driver_add_groups(drv, drv->groups);
230 if (ret)
231 bus_remove_driver(drv);
232 return ret;
233}
234EXPORT_SYMBOL_GPL(driver_register);
644/**
645 * bus_add_driver - Add a driver to the bus.
646 * @drv: driver.
647 */
648int bus_add_driver(struct device_driver *drv)
649{
650 struct bus_type *bus;
651 struct driver_private *priv;
652 int error = 0;
653
654 bus = bus_get(drv->bus);
655 if (!bus)
656 return -EINVAL;
657
658 pr_debug("bus: \'%s\': add driver %s/n", bus->name, drv->name);
659
660 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
661 if (!priv) {
662 error = -ENOMEM;
663 goto out_put_bus;
664 }
665 klist_init(&priv->klist_devices, NULL, NULL);
666 priv->driver = drv;
667 drv->p = priv;
668 priv->kobj.kset = bus->p->drivers_kset;
669 error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,
670 "%s", drv->name);
671 if (error)
672 goto out_unregister;
673
674 if (drv->bus->p->drivers_autoprobe) {
675 error = driver_attach(drv);
676 if (error)
677 goto out_unregister;
678 }
679 klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
680 module_add_driver(drv->owner, drv);
681
682 error = driver_create_file(drv, &driver_attr_uevent);
683 if (error) {
684 printk(KERN_ERR "%s: uevent attr (%s) failed/n",
685 __FUNCTION__, drv->name);
686 }
687 error = driver_add_attrs(bus, drv);
688 if (error) {
689 /* How the hell do we get out of this pickle? Give up */
690 printk(KERN_ERR "%s: driver_add_attrs(%s) failed/n",
691 __FUNCTION__, drv->name);
692 }
693 error = add_bind_files(drv);
694 if (error) {
695 /* Ditto */
696 printk(KERN_ERR "%s: add_bind_files(%s) failed/n",
697 __FUNCTION__, drv->name);
698 }
699
700 kobject_uevent(&priv->kobj, KOBJ_ADD);
701 return error;
702out_unregister:
703 kobject_put(&priv->kobj);
704out_put_bus:
705 bus_put(bus);
706 return error;
707}
如果总线上的driver是自动probe的话,则将该总线上的driver和device绑定起来。