#1 platform设备驱动模型数据结构
一般总线驱动设备数据结构
驱动 总线 设备
device_driver bus_type device
一般总线驱动设备数据结构
驱动 总线 设备
platform_driver platform_bus_type platform_device
#2 platform总线注册
platform_bus_init
bus_register(&platform_bus_type);//注册之前要先构造platform总线数据结构,如下:
struct bus_type platform_bus_type = {
.name = "platform",
.dev_groups = platform_dev_groups,
.match = platform_match,
.uevent = platform_uevent,
.pm = &platform_dev_pm_ops,
};
#3 platform驱动
数据结构如下:
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;
};
使用platform驱动时需要向内核注册,流程如下:
platform_driver_register
__platform_driver_register
设置driver的probe为platform_drv_prob;
driver_register
向内核注册驱动的时候,如果驱动和设备匹配成功,就会执行platform_drv_prob函数;
#4 platform设备
数据结构如下:
struct platform_device
{
const char *name;
int id;
bool id_auto;
struct device dev;
u32 num_resources;
struct resource *resource;
const struct platform_device_id *id_entry;
char *driver_override; /* Driver name to force a match */
/* MFD cell pointer */
struct mfd_cell *mfd_cell;
/* arch specific additions */
struct pdev_archdata archdata;
};
总结:
1.无设备树时,此时需要驱动工程师编写设备注册文件,使用platform_device_register向内核注册设备;
2.有设备树时,修改设备树的设备节点即可,内核会解析设备会,并将设备树还原成设备;
当设备与platform的驱动匹配以后,就会执行platform_driver结构中的probe函数;
#5 platform匹配过程
platform_match
of_driver_match_device //使用设备树时
acpi_driver_match_device
platform_match_id //根据platform_driver->id_table
strcmp(pdev->name, drv->name) //比较platform_device->name和platform_driver->name//无设备树时使用
匹配过程优先使用设备树方式,使用设备树时的匹配流程如下:
of_driver_match_device
of_match_device(const struct of_device_id *matches,const struct device *dev) //of_match_table保存了驱动支持的设备信息
of_match_node
__of_match_node
__of_device_is_compatible
__of_find_property(device, "compatible", NULL);//取出属性值