zoukankan      html  css  js  c++  java
  • Resouce, platform_device 和 platform_driver 的关系【转】

    转自:http://blog.csdn.net/uruita/article/details/7278313

    從2.6版本開始引入了platform這個概念,在開發底層驅動程序時,首先要確認的就是設備的資源信息,例如設備的地址,
    在2.6內核中將每個設備的資源用結構platform_device來描述,該結構體定義在kernelincludelinuxplatform_device.h中,

    struct platform_device {

     const char * name;
     u32  id;
     struct device dev;
     u32  num_resources;
     struct resource * resource;
    };

    該結構一個重要的元素是resource,該元素存入了最為重要的設備資源信息,定義在kernelincludelinuxioport.h中,
    struct resource {
     const char *name;
     unsigned long start, end;
     unsigned long flags;
     struct resource *parent, *sibling, *child;
    };

    下面舉個例子來說明一下:

    在kernelarcharmmach-pxapxa27x.c定義了
    static struct resource pxa27x_ohci_resources[] = {
     [0] = {
      .start  = 0x4C000000,
      .end    = 0x4C00ff6f,
      .flags  = IORESOURCE_MEM,
     },
     [1] = {
      .start  = IRQ_USBH1,
      .end    = IRQ_USBH1,
      .flags  = IORESOURCE_IRQ,
     },
    };

    這裡定義了兩組resource,它描述了一個usb host設備的資源,第1組描述了這個usb host設備所佔用的總線地址範圍,IORESOURCE_MEM表示第1組描述的是內存類型的資源信息,第2組描述了這個usb host設備的中斷號,IORESOURCE_IRQ表示第2組描述的是中斷資源信息。設備驅動會根據flags來獲取相應的資源信息。

    有了resource信息,就可以定義platform_device了:

    static struct platform_device ohci_device = {
     .name  = "pxa27x-ohci",
     .id  = -1,
     .dev  = {
      .dma_mask = &pxa27x_dmamask,
      .coherent_dma_mask = 0xffffffff,
     },
     .num_resources  = ARRAY_SIZE(pxa27x_ohci_resources),
     .resource       = pxa27x_ohci_resources,
    };

    有了platform_device就可以调用函数platform_add_devices向系統中添加该设备了,这里的实现是

    static int __init pxa27x_init(void)
    {
      return platform_add_devices(devices, ARRAY_SIZE(devices));
    }

    这里的pxa27x_init必须在设备驱动加载之前被调用,可以把它放到

    subsys_initcall(pxa27x_init);

    驱动程序需要实现结构体 struct platform_driver,参考 kerneldriverusbhostohci-pxa27.c,

    static struct platform_driver ohci_hcd_pxa27x_driver = {
     .probe  = ohci_hcd_pxa27x_drv_probe,
     .remove  = ohci_hcd_pxa27x_drv_remove,
    #ifdef CONFIG_PM
     .suspend = ohci_hcd_pxa27x_drv_suspend, 
     .resume  = ohci_hcd_pxa27x_drv_resume,
    #endif
     .driver  = {
      .name = "pxa27x-ohci",
     },
    };

    在驱动初始化函数中调用函数platform_driver_register()注册platform_driver,需要注意的是 ohci_device结构中name元素和ohci_hcd_pxa27x_driver结构中driver.name必須是相同的,这样在 platform_driver_register()注册时会对所有已注册的platform_device中的name和当前注册的 platform_driver的driver.name进行比较,只有找到相同的名称的platfomr_device才能注册成功,当注册成功时会调用platform_driver结构元素probe函数指针,这里就是ohci_hcd_pxa27x_drv_probe。

    当进入probe函数后,需要获取设备的资源信息,获取資源的函數有:
    struct resource * platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num);
    根据参数 type所指定类型,例如IORESOURCE_MEM,來获取指定的资源。
    struct int platform_get_irq(struct platform_device *dev, unsigned int num);
    获取資源中的中断号。
    struct resource * platform_get_resource_byname(struct platform_device *dev, unsigned int type, char *name);
    根据参数 name所指定的名称來获取指定的资源。
    int platform_get_irq_byname(struct platform_device *dev, char *name);
    根据参数 name所指定的名称来获取資源中的中断号。

  • 相关阅读:
    算法与数据结构 (四) 排序 一 交换类排序
    算法与数据结构 (三) 二叉树的简单应用 二叉查找树,二叉堆排序
    算法与数据结构 (二) 二叉树的简单实现,非递归的前序遍历 中序遍历 后序遍历
    算法与数据结构 (一) 链表,栈,队列的简单实现
    服务器端的redis和MySQL的远程连接的简单解决方案
    记一次自定义监听器使用spring 管理的bean的问题
    基于java开发的RBAC模型权限管理系统
    2019 本科java开发春招面经(实习)
    记一次Bootstrap框架下 使用Ajax失效的问题
    [转]在static代码块或static变量的初始化过程中使用ServiceManager提供的api的陷阱
  • 原文地址:https://www.cnblogs.com/sky-heaven/p/5063886.html
Copyright © 2011-2022 走看看