Linux驱动-platform设备驱动

#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);//取出属性值

你可能感兴趣的:(#,驱动,linux,驱动开发,运维)