本节用于介绍平台总线模型——注册platform驱动
编写driver.c的思路
首先定义一个platform_driver结构体变量,然后去实现结构体中的各个成员变量,那么当我们的driver 和device匹配成功的时候,就会执行probe函数,所以匹配成功以后的重点就在于probe函数的编写。
1、平台总线注册一个platform_driver
文件位置路径:include/linux/platform_device.h
1 2 3 4 5 6 7 8 9 10
| struct platform_driver { int (*probe)(struct platform_device *); int (*remove)(struct platform_device *); void (*shutdown)(struct platform_device *); int (*suspend)(struct platform_device *, pm_message_t state); int (*resume)(struct platform_device *); struct device_driver driver; const struct platform_device_id *id_table; bool prevent_deferred_probe; };
|
在struct platform_device_id结构体内还有一个name成员
文件位置路径:include/linux/mod_devicetable.h
1 2 3 4
| struct platform_device_id { char name[PLATFORM_NAME_SIZE]; kernel_ulong_t driver_data; };
|
这个里面的name的匹配优先级比较高,
2、填写platform_driver里面的device_driver结构体
文件位置路径:include/linux/device.h
1 2 3 4 5 6
| struct device_driver { ... const char *name; struct module *owner; ... };
|
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| int beep_probe(struct platform_device *pdev) { printk("beep_probe\n"); return 0; }
int beep_remove(struct platform_device *pdev) { printk("beep_remove\n"); return 0; }
struct platform_device_id beep_idtable = { .name = "beep_test" };
struct platform_driver beep_driver = { .probe = beep_probe, .remove = beep_remove, .driver = { .owner = THIS_MODULE, .name = "beep_test" }, .id_table = &beep_idtable };
|
3、注册和注销平台驱动函数
当使用上节的函数创建完成一个platform_driver后,使用platform_driver_register函数进行平台设备的注册
文件位置路径:include/linux/platform_device.h
实际函数位置路径:drivers/base/platform.c
1 2 3 4 5 6 7
| #define platform_driver_register(drv) \ __platform_driver_register(drv, THIS_MODULE) extern int __platform_driver_register(struct platform_driver *, struct module *);
|
1 2 3 4 5 6 7 8
| extern void platform_driver_unregister(struct platform_driver *); void platform_driver_unregister(struct platform_driver *drv) { driver_unregister(&drv->driver); } EXPORT_SYMBOL_GPL(platform_driver_unregister);
|