详解Linux2.6内核中基于platform机制的驱动模型 (经典) (7)

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绑定起来。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwjjds.html