首先,如果对platform设备和驱动的注册机制不熟悉的话,可以先看一下大神的博客
http://blog.csdn.net/zqixiao_09/article/details/50888795
一、下面逐一分析一下每一个函数的功能
1、platform_device_register //把设备注册到platform bus上
1)platform_device_add
2)pdev->dev.bus = &platform_bus_type; //指明设备要挂载总线类型
3)device_add
4)bus_add_device //把设备放到相应的总线上面
5)bus_probe_device
6)device_attach //尝试绑定相应的驱动
7)bus_for_each_drv
8)__device_attach
9)driver_match_device //调用platform_match匹配相应的驱动,先匹配id table,再返回比较驱动的名字
//1、注册设备前,驱动已经注册,那么则会继续执行相应设备的probe函数
//2、如果注册设备前,驱动没有被注册,那么就仅把设备注册到总线上
10)driver_probe_device(drv, dev)
11)really_probe(dev, drv)
12)dev->bus->probe(dev)/drv->probe(dev) //执行驱动的probe,对设备进行初始化
13)put_device //把设备放进内核
2、platform_driver_register //把驱动注册到platform bus上
1)drv->driver.bus = &platform_bus_type;//指明驱动要挂载总线类型
2)driver_register
3)bus_add_driver //把driver添加到bus上面
4)driver_attach
5)bus_for_each_dev //查找相应的设备是否已经在总线上注册
6)__driver_attach(struct device * dev, void * data)
7)driver_match_device(drv, dev) //与上面platform_match的一样
//1、注册驱动前,设备已经注册,那么则会继续执行相应设备的probe函数
//2、如果注册驱动前,设备没有被注册,那么就仅把驱动注册到总线上
8)driver_probe_device(drv, dev)
9)really_probe(dev, drv)
10)dev->bus->probe(dev)/drv->probe(dev) //执行驱动的probe,对设备进行初始化
11)klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers); //把driver放在bus
下面分析一下关键函数
int bus_add_driver(struct device_driver *drv)
{
......
if (drv->bus->p->drivers_autoprobe) {
error = driver_attach(drv); //驱动开始匹配设备
if (error)
goto out_unregister;
}
......
}
int driver_attach(struct device_driver *drv)
{
return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach); //在bus上面轮询匹配设备
}
//遍历bus的函数
int bus_for_each_dev(struct bus_type *bus, struct device *start,
void *data, int (*fn)(struct device *, void *))
{
struct klist_iter i;
struct device *dev;
int error = 0;
if (!bus)
return -EINVAL;
klist_iter_init_node(&bus->p->klist_devices, &i,
(start ? &start->p->knode_bus : NULL));
while ((dev = next_device(&i)) && !error)
error = fn(dev, data);
klist_iter_exit(&i);
return error;
}
//实际的匹配函数
static int __driver_attach(struct device *dev, void *data)
{
struct device_driver *drv = data;
/*
* Lock device and try to bind to it. We drop the error
* here and always return 0, because we need to keep trying
* to bind to devices and some drivers will return an error
* simply if it didn't support the device.
*
* driver_probe_device() will spit a warning if there
* is an error.
*/
//如果没有找到相应的设备 则退出
if (!driver_match_device(drv, dev))
return 0;
//如果找到相应的设备 则执行driver的probe对设备进行初始化工作
if (dev->parent) /* Needed for USB */
device_lock(dev->parent);
device_lock(dev);
if (!dev->driver)
driver_probe_device(drv, dev);
device_unlock(dev);
if (dev->parent)
device_unlock(dev->parent);
return 0;
}
3、device_register
其实device_register就是platform_device_register的父本,platform_device_register在device_register的基础上添加了platform_device一些个性的内容,如果没有把设备注册成platform device的情况,一般都会使用device_register来注册设备,如misc_register注册设备时。
4、driver_register
driver_register也一样,就是platform_driver_register的父本。
二、下面结合实例说明一下
#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#define DRIVER_NAME "hello_driver"//用于在总线上适配的驱动名字
#define DEVICE_NAME "hello_device"//生成的设备节点名字
static int hello_release(struct inode *inode, struct file *file){
printk("hello release\n");
return 0;
}
static int hello_open(struct inode *inode, struct file *file){
printk("hello open\n");
return 0;
}
static struct file_operations hello_ops = {
.owner = THIS_MODULE,
.open = hello_open,
.release = hello_release,
};
static struct miscdevice hello_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,//设备节点名
.fops = &hello_ops,
};
//如果总线匹配成功 就会执行probe函数
static int hello_probe(struct platform_device *pdv){
printk("hello_probe\n");
misc_register(&hello_dev);
return 0;
}
static int hello_remove(struct platform_device *pdv){
printk("hello_remove\n");
misc_deregister(&hello_dev);
return 0;
}
static void hello_shutdown(struct platform_device *pdv){
;
}
static int hello_suspend(struct platform_device *pdv,pm_message_t pmt){
return 0;
}
static int hello_resume(struct platform_device *pdv){
return 0;
}
//创建设备
static struct platform_device hello_device=
{
.name = DRIVER_NAME, //用于总线匹配
.id = -1,
};
//创建驱动
struct platform_driver hello_driver = {
.probe = hello_probe,
.remove = hello_remove,
.shutdown = hello_shutdown,
.suspend = hello_suspend,
.resume = hello_resume,
.driver = {
.name = DRIVER_NAME, //用于总线匹配
.owner = THIS_MODULE,
}
};
static int hello_init(void)
{
int DriverState;
platform_device_register(&hello_device);
printk(KERN_EMERG "hello_init!\n");
//打印信息使用dmesg查看
//执行platform_driver_register后 适配完 就会执行
//hello_probe,即先打印hello_probe信息,才会打印
//tDriverState信息
DriverState = platform_driver_register(&hello_driver);
printk(KERN_EMERG "\tDriverState is %d\n",DriverState);
return 0;
}
static void hello_exit(void)
{
printk(KERN_EMERG "hello_exit!\n");
platform_driver_unregister(&hello_driver);
platform_device_unregister(&hello_device);
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");