linux内核radeon gpu源码解析5 —— drm_get_pci_dev函数详解2
上一篇讲到了drm_get_pci_dev函数的第1个函数:drm_dev_alloc。
不知读者还有没有印象,前一篇文章中讲drm_get_pci_dev函数的第1个函数drm_dev_alloc的时候,在函数注释中有这样一段话:
/*******************************************************************************************
* Initialize a new DRM device. No device registration is done.
* Call drm_dev_register() to advertice the device to user space and register it
* with other core subsystems. This should be done last in the device
* initialization sequence to make sure userspace can't access an inconsistent
* state.
********************************************************************************************/
注释的大致意思是说,注册DRM设备但是没有初始化,需要在初始化的最后调用drm_dev_register()进行注册。
这一篇就来讲这个drm_get_pci_dev函数的第2个函数:drm_dev_register。
调用处:ret = drm_dev_register(dev, ent->driver_data);
源码如下:
drivers/gpu/drm/drm_drv.c
/**
* drm_dev_register - Register DRM device
* @dev: Device to register
* @flags: Flags passed to the driver's .load() function
*
* Register the DRM device @dev with the system, advertise device to user-space
* and start normal device operation. @dev must be allocated via drm_dev_alloc()
* previously.
*
* Never call this twice on any device!
*
* NOTE: To ensure backward compatibility with existing drivers method this
* function calls the &drm_driver.load method after registering the device
* nodes, creating race conditions. Usage of the &drm_driver.load methods is
* therefore deprecated, drivers must perform all initialization before calling
* drm_dev_register().
*
* RETURNS:
* 0 on success, negative error code on failure.
*/
int drm_dev_register(struct drm_device *dev, unsigned long flags)
{
struct drm_driver *driver = dev->driver;
int ret;
mutex_lock(&drm_global_mutex);
ret = drm_minor_register(dev, DRM_MINOR_RENDER);
if (ret)
goto err_minors;
ret = drm_minor_register(dev, DRM_MINOR_PRIMARY);
if (ret)
goto err_minors;
ret = create_compat_control_link(dev);
if (ret)
goto err_minors;
dev->registered = true;
if (dev->driver->load) {
ret = dev->driver->load(dev, flags);
if (ret)
goto err_minors;
}
if (drm_core_check_feature(dev, DRIVER_MODESET))
drm_modeset_register_all(dev);
ret = 0;
DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
driver->name, driver->major, driver->minor,
driver->patchlevel, driver->date,
dev->dev ? dev_name(dev->dev) : "virtual device",
dev->primary->index);
goto out_unlock;
err_minors:
remove_compat_control_link(dev);
drm_minor_unregister(dev, DRM_MINOR_PRIMARY);
drm_minor_unregister(dev, DRM_MINOR_RENDER);
out_unlock:
mutex_unlock(&drm_global_mutex);
return ret;
}
EXPORT_SYMBOL(drm_dev_register);
重点讲一下这一段程序:
if (dev->driver->load) {
ret = dev->driver->load(dev, flags);
if (ret)
goto err_minors;
}
dev就是drm_dev_alloc函数中新分配并初始化的那个dev。dev->driver就是前一篇文章中最后提到的dev->driver = driver;,也就是说dev->driver实际上指向了kms_driver。那么dev->driver->load不言而喻,当然就指向struct drm_driver kms_driver 中的
.load = radeon_driver_load_kms,
这个函数是所有和GPU初始化相关的内容的起始点 。下一篇我们重点介绍。
在此顺便列出
DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
driver->name, driver->major, driver->minor,
driver->patchlevel, driver->date,
dev->dev ? dev_name(dev->dev) : "virtual device",
dev->primary->index);
中各个成员的值:
driver->name为kms_driver中的.name = DRIVER_NAME,DRIVER_NAME宏定义的值根据不同的驱动而不同,在radeon驱动中为如下定义(drivers/gpu/drm/radeon/radeon_drv.h中):
#define DRIVER_NAME "radeon"
如果是在amdgpu驱动中,则为(drivers/gpu/drm/amd/amdgpu/amdgpu_drv.h中):
#define DRIVER_NAME "amdgpu"
如果是在nouveau驱动中,则为(drivers/gpu/drm/nouveau/nouveau_drv.h中):
#define DRIVER_NAME "nouveau"
如果是在loongson驱动中,则为(drivers/gpu/drm/loongson/loongson_drv.c中):
#define DRIVER_NAME "loongson-drm"
driver->major为kms_driver中的.major = KMS_DRIVER_MAJOR,KMS_DRIVER_MAJOR宏定义的值同样根据不同的驱动而不同,在radeon驱动中为如下定义(drivers/gpu/drm/radeon/radeon_drv.c中):
#define KMS_DRIVER_MAJOR 2
如果是在amdgpu驱动中,则为(drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c中):
#define KMS_DRIVER_MAJOR 3
注意,这个宏定义只在radeon和amdgpu驱动中有,其他驱动中无此宏定义。
driver->minor为kms_driver中的.minor = KMS_DRIVER_MINOR,KMS_DRIVER_MINOR宏定义的值同样根据不同的驱动而不同,在radeon驱动中为如下定义(drivers/gpu/drm/radeon/radeon_drv.c中):
#define KMS_DRIVER_MINOR 50
如果是在amdgpu驱动中,则为(drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c中):
#define KMS_DRIVER_MINOR 27
注意,这个宏定义同样只在radeon和amdgpu驱动中有,其他驱动中无此宏定义。
driver->patch_level为kms_driver中的.patchlevel = KMS_DRIVER_PATCHLEVEL,KMS_DRIVER_PATCHLEVEL宏定义只存在于radeon驱动(drivers/gpu/drm/radeon/radeon_drv.c)和amdgpu驱动(drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c)中,且值相同:
#define KMS_DRIVER_PATCHLEVEL 0
driver->date为kms_driver中的.date = DRIVER_DATE,DRIVER_DATE宏定义的值根据不同的驱动而不同,在radeon驱动中为如下定义(drivers/gpu/drm/radeon/radeon_drv.h中):
#define DRIVER_DATE "20080528"
如果是在amdgpu驱动中,则为(drivers/gpu/drm/amd/amdgpu/amdgpu_drv.h中):
#define DRIVER_DATE "20150101"
如果是在nouveau驱动中,则为(drivers/gpu/drm/nouveau/nouveau_drv.h中):
#define DRIVER_DATE "20120801"
如果是在loongson驱动中,则为(drivers/gpu/drm/loongson/loongson_drv.c中):
#define DRIVER_DATE "20180328"
相关文章
- Linux下安全切换至Root权限方法(linux怎么切换到root用户)
- 调查Linux系统下文件夹大小的方式(linux获取文件夹大小)
- 探索Linux技术:实现稳定高效网络通讯(linux网络通讯)
- Linux源码精要:PDF详解(linux源码pdf)
- 结构Linux内核目录结构:探索未知世界(linux内核目录)
- 了解Linux项目源码:探索开源之路(linux项目源码)
- Linux 的灰色暮年:软件巨头依然强大(linux倒闭)
- 深入Linux内核:构建与调试源码(linux源码调试)
- v简单操作:Linux下使用mv命令移动目录(linux目录m)
- Linux下数据库管理,从入门到精通(数据库与linux)
- Linux系统下的广播命令深度解析(linux广播命令)
- 简易指南:如何在文本模式下安装Linux操作系统(文本模式安装linux)
- Linux 内核: 最新版本来袭!(linux内核最新版本)
- Linux内核之旅:视频教程精彩解析(linux 内核视频教程)
- Linux权限赋予的智慧(linux 给权限)