Linux设备管理(三)_总线设备的挂接

Linux设备管理(三)_总线设备的挂接

转载:https://www.cnblogs.com/xiaojiang1025/p/6201290.html

扒完了字符设备,我们来看看平台总线设备,平台总线是Linux中的一种虚拟总线,我们知道,总线+设备+驱动是Linux驱动模型的三大组件,设计这样的模型就是将驱动代码和设备信息相分离,对于稍微复杂一点的驱动,都要使用这种结构,我在"Linux设备管理(一)_kobject, kset,kobj_type分析"一文中提到过将一个设备或驱动挂载到总线就是将这个设备或驱动的kobject挂接到相应的总线kset下的设备kset或驱动kset中,本文就扒一扒内核中注册一个平台设备的源码,验证一下这个说法。整体的调用关系是:platform_device_register()->platform_device_add()->device_add()->kobject_add()

platform_device_register()

在平台设备编程模型中,我们将我们数据封装到一个platform_device结构中后,就可以将设备对象注册到平台总线上

platform_device_register()
--461--> device_initialize()初始化平台设备的父类device结构
--463--> platform_device_add(pdev)将设备挂接到总线设备链表,即注册

//drivers/base/platform.c

  37 struct device platform_bus = {
  38         .init_name      = "platform",
  39 };

 459 int platform_device_register(struct platform_device *pdev)  
 460 {
 461         device_initialize(&pdev->dev);		
 462         arch_setup_pdev_archdata(pdev);
 463         return platform_device_add(pdev);
 464 }

device_initialize()主要是对平台设备的父类device结构进行一些初始化工作

device_initialize()
--702-->dev->kobj.kset = devices_kset;使用全局的devices_kset对象初始化设备的kset
--703-->kobject_init(&dev->kobj, &device_ktype);使用全局的device_ktype对象初始化设备的kobj对应的kobj_type
--704-->INIT_LIST_HEAD(&dev->dma_pools);初始化设备list_head结构,用于后序的链接

//drivers/base/core.c
 700 void device_initialize(struct device *dev)   
 701 {
 702         dev->kobj.kset = devices_kset;
 703         kobject_init(&dev->kobj, &device_ktype);
 704         INIT_LIST_HEAD(&dev->dma_pools);
	     ...
 714 }

platform_device_add()

这个函数才开始真正把平台设备对象挂接到平台总线上

platform_device_add()
--353-->使新的设备的kobject->parent指向全局的平台设备kobject对象
--355-->使设备的总线类型指针指向平台总线对象
--403-->将设备挂接到相应的总线

//drivers/base/platform.c
 345 int platform_device_add(struct platform_device *pdev)
 346 {
 347         int i, ret;
	     ...
 352         if (!pdev->dev.parent)
 353                 pdev->dev.parent = &platform_bus;			//挂到平台总线
 354 
 355         pdev->dev.bus = &platform_bus_type;
	     ...                                                      
 403         ret = device_add(&pdev->dev);
 404         if (ret == 0)
 405                 return ret;
	     ...
 421 }

device_add()

之前的工作已经准备好了一个平台设备对象,接下来的工作就是将这个设备挂接到总线上,注册任务就算完成了。

device_add()
--1074-->将设备的kobj挂接到之前填充好的parent的链表中,即平台总线的链表。

//drivers/base/platform.c
1025 int device_add(struct device *dev)
1026 {
1027         struct device *parent = NULL;
1028         struct kobject *kobj;
1029         struct class_interface *class_intf;
1030         int error = -EINVAL;
1031                                     
1032         dev = get_device(dev);
	     ...
1071 
1072         /* first, register with generic layer. */
1073         /* we require the name to be set before, and pass NULL */
1074         error = kobject_add(&dev->kobj, dev->kobj.parent, NULL);
	     ...
1138 done:
1139         put_device(dev);
1140         return error;

分类: Linux驱动开发

标签: Linux设备管理总线设备的挂接

« 上一篇: Linux设备管理(二)_从cdev_add说起
» 下一篇: Linux设备管理(四)_从sysfs回到ktype

©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值