中,代码如下:
48 struct platform_driver {
49 int (*probe)(struct platform_device *);
50 int (*remove)(struct platform_device *);
51 void (*shutdown)(struct platform_device *);
52 int (*suspend)(struct platform_device *, pm_message_t state);
53 int (*suspend_late)(struct platform_device *, pm_message_t state);
54 int (*resume_early)(struct platform_device *);
55 int (*resume)(struct platform_device *);
56 struct device_driver driver;
57};
可见,它包含了设备操作的几个功能函数,同时包含了一个device_driver结构,说明device_driver是 platform_driver的基类。驱动程序中需要初始化这个变量。下面看一下这个变量的定义,位于
#linux+v2.6.25/include/linux/device.h#L121中:
121struct device_driver {
122 const char *name;
123 struct bus_type *bus;
124
125 struct module *owner;
126 const char *mod_name; /* used for built-in modules */
127
128 int (*probe) (struct device *dev);
129 int (*remove) (struct device *dev);
130 void (*shutdown) (struct device *dev);
131 int (*suspend) (struct device *dev, pm_message_t state);
132 int (*resume) (struct device *dev);
133 struct attribute_group **groups;
134
135 struct driver_private *p;
136};
device_driver提供了一些操作接口,但其并没有实现,相当于一些虚函数,由派生类platform_driver进行重载,无论何种类 型的 driver都是基于device_driver派生而来的,具体的各种操作都是基于统一的基类接口的,这样就实现了面向对象的设计。
需要注意这两个变量:name和owner。其作用主要是为了和相关的platform_device关联起来,owner的作用是说明模块的所有者,驱动程序中一般初始化为THIS_MODULE。
device_driver结构中也有一个name变量。platform_driver从字面上来看就知道是设备驱动。设备驱动是为谁服务的呢?当然是设备了。内核正是通过这个一致性来为驱动程序找到资源,即 platform_device中的resource。
5 driver_register 和platform_driver_register
内核提供的platform_driver结构体的注册函数为platform_driver_register(),其原型定义在 文件中,具体实现代码如下:
439/**
440 * platform_driver_register
441 * @drv: platform driver structure
442 */
443int platform_driver_register(struct platform_driver *drv)
444{
445 drv->driver.bus = &platform_bus_type;
/*设置成platform_bus_type这个很重要,因为driver和device是通过bus联系在一起的,具体在本例中是通 过 platform_bus_type中注册的回调例程和属性来是实现的, driver与device的匹配就是通过 platform_bus_type注册的回调例程platform_match ()来完成的。*/
446 if (drv->probe)
447 drv->driver.probe = platform_drv_probe;
//在really_probe函数中,回调了platform_drv_probe函数