linux驱动之platform
平台驱动注册
#define platform_driver_register(drv) \
__platform_driver_register(drv, THIS_MODULE)
int __platform_driver_register(struct platform_driver *drv,
struct module *owner)
{
//THIS_MODULE代表模块自身
drv->driver.owner = owner;
//平台总线
drv->driver.bus = &platform_bus_type;
if (drv->probe)
drv->driver.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 platform_driver {
//device和driver匹配成功后调用,用于初始化
int (*probe)(struct platform_device *);
//driver卸载时调用
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;
//id_table->name和设备树的compatible进行字符匹配
const struct platform_device_id *id_table;
//是否延迟匹配
bool prevent_deferred_probe;
};
struct platform_device_id {
char name[PLATFORM_NAME_SIZE];
kernel_ulong_t driver_data;
};
struct bus_type platform_bus_type = {
.name = "platform",
.dev_groups = platform_dev_groups,
.match = platform_match,
.uevent = platform_uevent,
.pm = &platform_dev_pm_ops,
};
static int platform_drv_probe(struct device *_dev)
{
//使用container_of()获取drv和dev
struct platform_driver *drv = to_platform_driver(_dev->driver);
struct platform_device *dev = to_platform_device(_dev);
int ret;
//_dev->of_node是设备树节点
//根据设备树信息设置时钟
ret = of_clk_set_defaults(_dev->of_node, false);
...
ret = dev_pm_domain_attach(_dev, true);
if (ret != -EPROBE_DEFER) {
ret = drv->probe(dev);
if (ret)
dev_pm_domain_detach(_dev, true);
}
if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) {
...
}
return ret