Linux平台驱动分析

/*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函数。这个函数一般都是和硬件相关的操作在里面。
*/



你可能感兴趣的:(嵌入式)