前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux平台驱动分析

Linux平台驱动分析

作者头像
DragonKingZhu
发布2022-05-08 15:45:49
1.4K0
发布2022-05-08 15:45:49
举报
文章被收录于专栏:Linux内核深入分析
代码语言:javascript
复制
/*platform总线,驱动,设备模型。 这是一种机制。这样会使得驱动编写方便,便于维护*/

/*platform总线是一种虚拟的总线。 其实platform总线也是当作设备*/

/*******************************platform总线******************************************************/
int __init platform_bus_init(void)
{
	int error;

	early_platform_cleanup();
	
	/*注册一个设备, 名为platform*/
	error = device_register(&platform_bus);
	if (error)
		return error;
		
	/* 注册一个总线,总线类型为platform_bus_type */
	error =  bus_register(&platform_bus_type);
	if (error)
		device_unregister(&platform_bus);
	return error;
}

/*platform总线的名字*/
struct device platform_bus = {
	.init_name	= "platform",
};

/*platform 总线设备类型*/
struct bus_type platform_bus_type = {
	.name		= "platform",							//总线名字
	.dev_attrs	= platform_dev_attrs, //设备属性
	.match		= platform_match,       //总线匹配函数
	.uevent		= platform_uevent,			//热插拔函数
	.pm		= &platform_dev_pm_ops,
};

/*******************************platform驱动******************************************************/

/*平台驱动注册*/
int platform_driver_register(struct platform_driver *drv)
{
	return driver_register(&drv->driver);
}

int driver_register(struct device_driver *drv)
{
	ret = bus_add_driver(drv);
}
//Add a driver to the bus.
int bus_add_driver(struct device_driver *drv)
{
	driver_attach(drv);	
}

int driver_attach(struct device_driver *drv)
{
	return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
}

//回调函数
static int __driver_attach(struct device *dev, void *data)
{
	if (!driver_match_device(drv, dev))
		return 0;
}

//用总线的match函数进行匹配
static inline int driver_match_device(struct device_driver *drv,
				      struct device *dev)
{
	return drv->bus->match ? drv->bus->match(dev, drv) : 1;
}

//通过设备的名称和驱动的名称想匹配
static int platform_match(struct device *dev, struct device_driver *drv)
{
	/* fall-back to driver name match */
	return (strcmp(pdev->name, drv->name) == 0);  	
}

/*总结: 把新注册的plarform_drv放入drv链表中, 从platform_dev链表中依次取出每一个dev,用bus的match函数匹配。
  而bus的match函数是通过匹配设备和驱动的name的。如果相互匹配,然后就调用drv的probe函数。
*/

/*******************************platform设备******************************************************/

//平台设备注册
int platform_device_register(struct platform_device *pdev)
{
	device_initialize(&pdev->dev);
	return platform_device_add(pdev);
}


platform_device_add()->device_add()->bus_probe_device()->device_attach()->__device_attach()->driver_probe_device()->really_probe()

static int really_probe(struct device *dev, struct device_driver *drv)
{
	if (dev->bus->probe) {
		ret = dev->bus->probe(dev);	
}


/*总结: 当一个新的platform设备注册到platform总线时, 会把platform设备放入到platform_bus中的dev链表中。 然后与platform_driver中的链表一一比较。 如果匹配成功
  则会调用platform_bus中probe函数。 其实和piatform驱动注册时的流程是一样的。


	其实,platform总线, 设备, 驱动只是一种机制。 这种机制可以方便编程。
	如果要编写基于platform总线设备驱动模型的驱动。 对于程序员来说只需要编写platform设备文件和platform驱动文件。
	
	platform_dev文件中需要定义设备的资源等。
	platform_drv文件中最主要的是编写probe函数。这个函数一般都是和硬件相关的操作在里面。
*/
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015-01-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档