kernel版本:4.4.143
一、注册 platform_device 的过程
注册platform_device有两个入口
1.device_node转换为platform_device过程中
device_node转换为platform_device过程中,在of_platform_device_create_pdata函数中会调用of_device_add(dev)
int of_device_add(struct platform_device *ofdev)
int device_add(struct device *dev)
......
第一种注册platform_device的过程可参考设备树(三):device_node转换为platform_device
2.调用platform_device_register注册过程
int platform_device_register(struct platform_device *pdev)
int platform_device_add(struct platform_device *pdev)
int device_add(struct device *dev)
........
之后两个注册入口走下面的公共路径
int device_add(struct device *dev)
void bus_probe_device(struct device *dev)
void device_initial_probe(struct device *dev)
static int __device_attach(struct device *dev, bool allow_async)
static int __device_attach_driver(struct device_driver *drv, void *_data)
static inline int driver_match_device(struct device_driver *drv, struct device *dev)
return drv->bus->match ? drv->bus->match(dev, drv) : 1;
**最终调用platform_bus_type中的match函数指向的函数,即 static int platform_match(struct device dev, struct device_driver drv) //drivers\base\Platform.c
二、注册platform_deriver的过程
platform_deriver注册会在具体驱动中通过调用platform_driver_probe开始,例如
static int rockchip_cpuinfo_probe(struct platform_device *pdev) //pdev指向与该驱动匹配成功的platform_device
{
struct device *dev = &pdev->dev;
............
}
static const struct of_device_id rockchip_cpuinfo_of_match[] = {
{ .compatible = "rockchip,cpuinfo", },
{ },
};
MODULE_DEVICE_TABLE(of, rockchip_cpuinfo_of_match);
static struct platform_driver rockchip_cpuinfo_driver = {
.probe = rockchip_cpuinfo_probe,
.driver = {
.name = "rockchip-cpuinfo",
.of_match_table = rockchip_cpuinfo_of_match,
},
};
static int __init rockchip_cpuinfo_init(void)
{
return platform_driver_register(&rockchip_cpuinfo_driver);
}
**最终结果和注册 platform_device一样,调用platform_bus_type中的match函数指向的函数,即 static int platform_match(struct device dev, struct device_driver drv) //drivers\base\Platform.c
#define platform_driver_probe(drv, probe) __platform_driver_probe(drv, probe, THIS_MODULE)
int __init_or_module __platform_driver_probe(struct platform_driver *drv,int (*probe)(struct platform_device *), struct module *module)
int __platform_driver_register(struct platform_driver *drv,struct module *owner)
int driver_register(struct device_driver *drv)
int bus_add_driver(struct device_driver *drv)
int driver_attach(struct device_driver *drv)
static int __driver_attach(struct device *dev, void *data)
static inline int driver_match_device(struct device_driver *drv,struct device *dev)
{
return drv->bus->match ? drv->bus->match(dev, drv) : 1;
}
三、platform_device与platform_driver的匹配
匹配过程按优先顺序如下:
a. 比较 platform_dev.driver_override 和 platform_driver.drv->name
b. 比较 platform_dev.dev.of_node的compatible属性 和 platform_driver.drv->of_match_table
c. 比较 platform_dev.name 和 platform_driver.id_table->name
d. 比较 platform_dev.name 和 platform_driver.drv->name
有一个成功, 即匹配成功
static int platform_match(struct device *dev, struct device_driver *drv)
{
struct platform_device *pdev = to_platform_device(dev);
struct platform_driver *pdrv = to_platform_driver(drv);
/* When driver_override is set, only bind to the matching driver */
if (pdev->driver_override)
return !strcmp(pdev->driver_override, drv->name); //
/* Attempt an OF style match first */
if (of_driver_match_device(dev, drv)) // 驱动中of_device_id的compatible和device_node中的"compatible"属性比较
return 1;
/* Then try ACPI style match */
if (acpi_driver_match_device(dev, drv))
return 1;
/* Then try to match against the id table */
if (pdrv->id_table)
return platform_match_id(pdrv->id_table, pdev) != NULL; //platform_device的name和device_driver的platform_device_id中的name比较
/* fall-back to driver name match */
return (strcmp(pdev->name, drv->name) == 0); //platform_device的name和device_driver的name比较
}
在__driver_attach函数中platform_device与platform_driver匹配成功后,会调用driver_probe_device函数
int driver_probe_device(struct device_driver *drv, struct device *dev)
static int really_probe(struct device *dev, struct device_driver *drv)
dev->driver = drv;
drv->probe(dev); //调用device_driver的probe函数,最终调用platform_driver->probe
在driver_probe_device函数中接着完成2件事,
(1)platform_device的platform_device的device_driver 指向 platform_driver的device_driver
(2)调用驱动中的platform_driver.probe函数,至此一个platform_device或一个platform_driver注册完成
四、platform_driver几个重要的结构体
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;
};
struct device_driver {
const char*name;
struct bus_type*bus; //struct bus_type platform_bus_type = {
//.name= "platform",
//.dev_groups= platform_dev_groups,
//.match= platform_match,
//.uevent= platform_uevent,
//.pm= &platform_dev_pm_ops,
//};
struct module*owner;
const char*mod_name;/* used for built-in modules */
bool suppress_bind_attrs;/* disables bind/unbind via sysfs */
enum probe_type probe_type;
const struct of_device_id*of_match_table;
const struct acpi_device_id*acpi_match_table;
int (*probe) (struct device *dev); //指向platform_drv_probe(platform.c),最终调用platform_driver->probe
int (*remove) (struct device *dev); //指向platform_drv_remove(platform.c),最终调用platform_driver->remove
void (*shutdown) (struct device *dev); 指向platform_drv_shutdown(platform.c),最终调用platform_driver->shutdown
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; //p->driver指向自己
};
struct of_device_id {
charname[32];
chartype[32];
charcompatible[128];
const void *data;
};
struct platform_device_id {
char name[PLATFORM_NAME_SIZE];
kernel_ulong_t driver_data;
};