drm linux 内核,Linux DRM那些事-平台驱动匹配和探测

Linux内核通过module_platform_driver(rockchip_drm_platform_driver)函数注册RK3399 DRM框架驱动代码,该宏展开如下:

static int __init rockchip_drm_platform_driver_init(void)

{

return platform_driver_register(&rockchip_drm_platform_driver);

}

...

下面通过分析函数platform_driver_register()的调用流程,展示RK3399 DRM框架platform_device和platform_driver匹配过程和驱动探测过程。

具体调用流程如下:

rockchip_drm_platform_driver_init()-> ## rockchip_drm_drv.c

platform_driver_register()-> ## platform_device.h

__platform_driver_register()-> ## platform.c

driver_register()-> ## driver.c

bus_add_driver()-> ## bus.c

driver_attach()-> ## dd.c

bus_for_each_dev()-> ## bus.c

__driver_attach()-> ## dd.c

1.driver_match_device()-> ## base.h match

platform_match() ## platform.c 开始match

2.driver_probe_device()-> ## dd.c probe

really_probe()-> ## dd.c

platform_drv_probe()-> ## platform.c 开始probe

rockchip_drm_platform_probe() ## rockchip_drm_drv.c

一、match实现

在注册Linux内核platform总线时,相关的总线类型定义如下:

struct bus_type platform_bus_type = {

.name = "platform",

.dev_groups = platform_dev_groups,

.match = platform_match,

.uevent = platform_uevent,

.pm = &platform_dev_pm_ops,

};

EXPORT_SYMBOL_GPL(platform_bus_type);

在bus_type结构体中定义了platform device和platform driver的匹配函数platform_match(),具体实现如下:

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);

## 1.设备树匹配

/* Attempt an OF style match first */

if (of_driver_match_device(dev, drv))

return 1;

## 2.ACPI类型匹配(无)

/* Then try ACPI style match */

if (acpi_driver_match_device(dev, drv))

return 1;

## 3.id table匹配

/* Then try to match against the id table */

if (pdrv->id_table)

return platform_match_id(pdrv->id_table, pdev) != NULL;

## 4.device和driver名字匹配

/* fall-back to driver name match */

return (strcmp(pdev->name, drv->name) == 0);

}

platform device和platform driver的匹配方法包括:

1、设备树匹配

匹配方法:比较dts设备节点的compatible属性定义和驱动文件中of_device_id中的compatible定义是否相同。

注:RK3399 DRM驱动使用的是设备树匹配.

#1. rockchip_drm_drv.c compatible定义

static const struct of_device_id rockchip_drm_dt_ids[] = {

{ .compatible = "rockchip,display-subsystem", },

...

};

MODULE_DEVICE_TABLE(of, rockchip_drm_dt_ids);

static struct platform_driver rockchip_drm_platform_driver = {

...

.driver = {

.name = "rockchip-drm",

.of_match_table = rockchip_drm_dt_ids,

...

},

};

#2. rk3399.dtsi compatible定义

display_subsystem: display-subsystem {

compatible = "rockchip,display-subsystem";

...

};

2、ACPI类型匹配 (无)

3、id table匹配

4、device和driver名字匹配

二、probe实现

在实现了DRM的platform device和platform driver匹配后,会进入Linux内核的platform_driver中的probe探测函数进行DRM驱动探测函数的调用。platform_driver初始化如下:

int __platform_driver_register(struct platform_driver *drv,

struct module *owner)

{

drv->driver.owner = owner;

drv->driver.bus = &platform_bus_type;

drv->driver.probe = platform_drv_probe;

drv->driver.remove = platform_drv_remove;

drv->driver.shutdown = platform_drv_shutdown;

return driver_register(&drv->driver);

}

platform_drv_probe实现如下:

static int platform_drv_probe(struct device *_dev)

{

struct platform_driver *drv = to_platform_driver(_dev->driver);

struct platform_device *dev = to_platform_device(_dev);

int ret;

...

ret = dev_pm_domain_attach(_dev, true);

if (ret != -EPROBE_DEFER) {

if (drv->probe) {

## 调用各驱动的probe函数(例:DRM的rockchip_drm_platform_driver())

ret = drv->probe(dev);

if (ret)

dev_pm_domain_detach(_dev, true);

} else {

/* don't fail if just dev_pm_domain_attach failed */

ret = 0;

}

}

...

}

小结:

1、RK3399 DRM框架的platform device和platform driver在Linux内核platform bus的match函数中实现匹配。

2、RK3399 DRM驱动的probe是在Linux内核platform driver的probe中调用。

注:本文基于RockPI 4A单板的Debian系统 Linux4.4内核。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值