歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Linux設備管理(三)_總線設備的掛接

Linux設備管理(三)_總線設備的掛接

日期:2017/3/1 9:07:43   编辑:Linux編程

扒完了Linux字符設備,我們來看看平台總線設備,平台總線是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;

Copyright © Linux教程網 All Rights Reserved