注册struct platform_driver
platform_driver_register
driver_register
->bus_add_driver // add a driver to a bus;
-> driver_attach // 查找bus下所有设备,找与其匹配的
-> bus_for_each_dev(drv->bus,NULL,drv,__driver_attach)
-> __driver_attach // 检测每一个设备
-> driver_match_device // 每个设备都调用此函数,判断是否与当前驱动匹配。
// 实际上是执行 dev->bus->match
(匹配成功执行)driver_probe_device
->really_probe
-> drv->probe // 驱动与设备匹配时,执行drive->probe
向总线注册驱动时,会检查当前总线下的所有设备,有没有与此驱动匹配的设备。
若有则执行驱动结构体里面的 probe 成员函数
platform_device_register
device_register
->device_add
->bus_add_device
bus_probe_device
->device_attach(dd.c)
->bus_for_each_drv(dev->bus, NULL, dev, __device_attach)
->__device_attach // 查找bus下的每一个驱动
// 都执行此函数
->driver_match_device(drv, dev) // 判断每一个驱动设备是否匹配
// 实际上内部调用的就是 drv->bus->match
若匹配则执行driver_probe_match
->really_probe
-> drv->probe
不管是先注册设备还是先注册驱动,驱动和设备匹配以后,drv->probe就会执行。
此probe由驱动编写人员编写的,以后会将常与此函数打交道。
platform_init()
//platform 总线是 bus_type 的一个具体实例
//定义在文件 drivers/base/platform.c
struct bus_type platform_bus_type = {
/* 总线名字 /sys/bus/platform */
.name = "platform",
.dev_groups = platform_dev_groups,
/* pdev 和 pdrv 的匹配函数*/
.match = platform_match,
.uevent = platform_uevent,
.pm = &platform_dev_pm_ops,
};
对于platform平台而言,函数 platform_match
负责匹配 platform驱动
和 platform设备
。
platform_driver
//此结构体定义在文件 include/linux/platform_device.h 中
struct platform_driver {
/*pdev 和 pdrv 匹配成功后会执行 pdrv->probe 函数 */
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_device
struct platform_device {
/* 用于无设备树的匹配,和 pdrv->drv->name */
const char *name;
int id;
bool id_auto;
struct device dev;
u32 num_resources;
/* 相比于 dev 新增加的内容 */
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;
};
resources
struct resource
{
resource_size_t start;
resource_size_t end;
const char *name;
/* 表示 resource 类型
* 定义在 ioport.h
*/
unsigned long flags;
struct resource *parent, *sibling, *child;
};
platform_init()
int __init platform_bus_init(void)
{
int error;
early_platform_cleanup();
error = device_register(&platform_bus);//添加设备
if (error)
return error;
error = bus_register(&platform_bus_type);//注册platform_bus_type
if (error)
device_unregister(&platform_bus);
return error;
}
probe调用流程
分析platform.c
platform_driver_register
//初始化platform_driver中的probe 接口
static struct platform_driver s3c24xx_led_driver = {
.probe = led_probe,
.remove = led_remove,
.driver = {
.name = "platform_led",
.owner = THIS_MODULE,
},
};
int platform_driver_register(struct platform_driver *drv)
{
drv->driver.bus = &platform_bus_type; //设置platform_drv下的driver.bus = platform_bus
if (drv->probe)
drv->driver.probe = platform_drv_probe;//platform_drv_probe,负责调用上层驱动
if (drv->remove)
drv->driver.remove = platform_drv_remove;
if (drv->shutdown)
drv->driver.shutdown = platform_drv_shutdown;
return driver_register(&drv->driver);//添加struct device_drive
}
driver_register()
int driver_register(struct device_driver *drv)
{
int ret;
struct device_driver *other;
BUG_ON(!drv->bus->p);
if ((drv->bus->probe && drv->probe) ||
(drv->bus->remove && drv->remove) ||
(drv->bus->shutdown && drv->shutdown))
printk(KERN_WARNING "Driver '%s' needs updating - please use "
"bus_type methods\n", drv->name);
other = driver_find(drv->name, drv->bus);//分析见下面,检查是否已经注册过了
if (other) {
printk(KERN_ERR "Error: Driver '%s' is already registered, "
"aborting...\n", drv->name);
return -EBUSY;
}
ret = bus_add_driver(drv);//注册到drv->bus
if (ret)
return ret;
ret = driver_add_groups(drv, drv->groups);
if (ret)
bus_remove_driver(drv);
return ret;
}
driver_find()
struct kobject {
const char *name;
struct list_head entry;
struct kobject *parent;
struct kset *kset; //kset 是嵌入相同类型结构的 kobject 集合,包含很多kobject ,是kobject的顶层容器,把kset 添加到系统中,会在sysfs中创建一个目录,kset中的每个kobject都会在sysfs中表述
struct kobj_type *ktype;
struct sysfs_dirent *sd;
struct kref kref;
unsigned int state_initialized:1;
unsigned int state_in_sysfs:1;
unsigned int state_add_uevent_sent:1;
unsigned int state_remove_uevent_sent:1;
unsigned int uevent_suppress:1;
};
struct subsys_private {
struct kset subsys;
struct kset *devices_kset;
struct list_head interfaces;
struct mutex mutex;
struct kset *drivers_kset;//driver的kobject集合
struct klist klist_devices;
struct klist klist_drivers;
struct blocking_notifier_head bus_notifier;
unsigned int drivers_autoprobe:1;
struct bus_type *bus;
struct kset glue_dirs;
struct class *class;
};
struct driver_private {
struct kobject kobj;
struct klist klist_devices;
struct klist_node knode_bus;
struct module_kobject *mkobj;
struct device_driver *driver;
};
struct device_driver *driver_find(const char *name, struct bus_type *bus)
{
//bus_type的p是subsys_private类型,
//在bus的private 的 kset中找name 的kobject
struct kobject *k = kset_find_obj(bus->p->drivers_kset, name);
struct driver_private *priv;
if (k) {
/* Drop reference added by kset_find_obj() */
kobject_put(k);
priv = to_driver(k);//priv = container_of(k, struct driver_private, kobj)
//driver_private -> kobj 会 添加到 bus_type -> subsys_private -> ksets中
return priv->driver;//dirver_private -> driver 指向 device_driver
}
return NULL;
}
bus_add_driver()
struct device_driver {
const char *name;
struct bus_type *bus;
struct module *owner;
const char *mod_name; /* used for built-in modules */
bool suppress_bind_attrs; /* disables bind/unbind via sysfs */
const struct of_device_id *of_match_table;
int (*probe) (struct device *dev);
int (*remove) (struct device *dev);
void (*shutdown) (struct device *dev);
int (*suspend) (struct device *dev, pm_message_t state);
int (*resume) (struct device *dev);
const struct attribute_group **groups;
const struct dev_pm_ops *pm;
struct driver_private *p;
};
struct driver_private {
struct kobject kobj;
struct klist klist_devices;
struct klist_node knode_bus;
struct module_kobject *mkobj;
struct device_driver *driver;
};
int bus_add_driver(struct device_driver *drv)
{
struct bus_type *bus;
struct driver_private *priv;
int error = 0;
bus = bus_get(drv->bus);
if (!bus)
return -EINVAL;
pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name);
priv = kzalloc(sizeof(*priv), GFP_KERNEL); //申请driver_private 结构体
if (!priv) {
error = -ENOMEM;
goto out_put_bus;
}
/*driver 和 device 匹配后 ,会把设备加到driver 的 p -> klist_devices
klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices);
*/
klist_init(&priv->klist_devices, NULL, NULL);
priv->driver = drv; //private 和 driver 关联
drv->p = priv;
priv->kobj.kset = bus->p->drivers_kset; //private的kobj-> kset 指向 bus_type->p->driver_kset
error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,
"%s", drv->name);//设置kobj的name
if (error)
goto out_unregister;
if (drv->bus->p->drivers_autoprobe) {
error = driver_attach(drv);//attach device,分析过程,见上图probe
if (error)
goto out_unregister;
}
klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers); //priv->knode_bus 添加到 bus->p-klist_drivers
module_add_driver(drv->owner, drv);
error = driver_create_file(drv, &driver_attr_uevent);
if (error) {
printk(KERN_ERR "%s: uevent attr (%s) failed\n",
__func__, drv->name);
}
error = driver_add_attrs(bus, drv);
if (error) {
/* How the hell do we get out of this pickle? Give up */
printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
__func__, drv->name);
}
if (!drv->suppress_bind_attrs) {
error = add_bind_files(drv);
if (error) {
/* Ditto */
printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
__func__, drv->name);
}
}
kobject_uevent(&priv->kobj, KOBJ_ADD);
return 0;
out_unregister:
kobject_put(&priv->kobj);
kfree(drv->p);
drv->p = NULL;
out_put_bus:
bus_put(bus);
return error;
}