Yuhang Zheng

第十四节、平台总线模型——注册platform驱动

N 人看过

本节用于介绍平台总线模型——注册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 *); //当driver和device匹配成功的时候,就会执行probe 函数
int (*remove)(struct platform_device *); //当driver和device任意一个remove的时候,就会执行这个函数
void (*shutdown)(struct platform_device *); //当设备收到shutdown命令的时候,就会执行这个函数
int (*suspend)(struct platform_device *, pm_message_t state); //当设备收到suspend休眠命令的时候,就会执行这个函数
int (*resume)(struct platform_device *); ////当设备收到resume唤醒命令的时候,就会执行这个函数
struct device_driver driver;
const struct platform_device_id *id_table; //这个里面的name优先级比device_driver结构体里面的name的优先级比较高
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; //常用,用于平台设备与平台驱动的匹配,会在/sys/bus/platform/driver/下生成name的节点
struct module *owner; //模块的所有者,一般是THIS_MODULE
...
};

示例:

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 *);

//参数
//pdev:要注册的平台驱动
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);
//参数
//pdev:要注销的平台驱动