zoukankan      html  css  js  c++  java
  • linux platform设备与驱动

      

    174 struct platform_driver {
    175     int (*probe)(struct platform_device *);
    176     int (*remove)(struct platform_device *);
    177     void (*shutdown)(struct platform_device *);
    178     int (*suspend)(struct platform_device *, pm_message_t state);
    179     int (*resume)(struct platform_device *);
    180     struct device_driver driver;
    181     const struct platform_device_id *id_table;
    182     bool prevent_deferred_probe;
    183 };

     259 struct device_driver {
     260     const char      *name;
     261     struct bus_type     *bus;
     262 
     263     struct module       *owner;
     264     const char      *mod_name;  /* used for built-in modules */
     265 
     266     bool suppress_bind_attrs;   /* disables bind/unbind via sysfs */
     267     enum probe_type probe_type;
     268 
     269     const struct of_device_id   *of_match_table;    //device tree通过这个去匹配
     270     const struct acpi_device_id *acpi_match_table;
     271 
     272     int (*probe) (struct device *dev);
     273     int (*remove) (struct device *dev);
     274     void (*shutdown) (struct device *dev);
     275     int (*suspend) (struct device *dev, pm_message_t state);
     276     int (*resume) (struct device *dev);
     277     const struct attribute_group **groups;
     278 
     279     const struct dev_pm_ops *pm;
     280 
     281     struct driver_private *p;
     282 };
     22 struct platform_device {
     23     const char  *name;
     24     int     id;
     25     bool        id_auto;
     26     struct device   dev;
     27     u32     num_resources;
     28     struct resource *resource;
     29 
     30     const struct platform_device_id *id_entry;
     31     char *driver_override; /* Driver name to force a match */
     32 
     33     /* MFD cell pointer */
     34     struct mfd_cell *mfd_cell;
     35 
     36     /* arch specific additions */
     37     struct pdev_archdata    archdata;
     38 };

    以上是头文件的结构体定义

    129 static const struct of_device_id dw_spi_mmio_of_match[] = {
    130     { .compatible = "snps,dw-apb-ssi", },
    131     { /* end of table */}
    132 };
    133 MODULE_DEVICE_TABLE(of, dw_spi_mmio_of_match);
    134 
    135 static struct platform_driver dw_spi_mmio_driver = {
    136     .probe      = dw_spi_mmio_probe,
    137     .remove     = dw_spi_mmio_remove,
    138     .driver     = {
    139         .name   = DRIVER_NAME,
    140         .of_match_table = dw_spi_mmio_of_match,
    141     },
    142 };
    143 module_platform_driver(dw_spi_mmio_driver);
    144 
    145 MODULE_AUTHOR("Jean-Hugues Deschenes <jean-hugues.deschenes@octasic.com>");
    146 MODULE_DESCRIPTION("Memory-mapped I/O interface driver for DW SPI Core");
    147 MODULE_LICENSE("GPL v2");

    以前的写法 : 

        struct platform_device s3c_device_usb = {  
                 .name    = "s3c2410-ohci",  //s3c6410-usb  
                 .id    = -1,  
                 .num_resources   = ARRAY_SIZE(s3c_usb_resource),  
                 .resource   = s3c_usb_resource,  
                 .dev              = {  
                         .dma_mask = &s3c_device_usb_dmamask,  
                         .coherent_dma_mask = 0xffffffffUL  
                     }  
        };  

    有了platform_device就可以调用函数platform_add_devices向系统中添加该设备了。系统中的设备资源都可以采用这种方式列举在一起,然后成一个指针数组,如:
    static struct platform_device *smdk6410_devices[] __initdata = { ...... &s3c_device_usbgadget, &s3c_device_usb, //jeff add. ...... } static struct platform_driver ohci_hcd_s3c2410_driver = { .probe = ohci_hcd_s3c2410_drv_probe, .remove = ohci_hcd_s3c2410_drv_remove, .shutdown = usb_hcd_platform_shutdown, /*.suspend = ohci_hcd_s3c2410_drv_suspend, */ /*.resume = ohci_hcd_s3c2410_drv_resume, */ .driver = { .owner = THIS_MODULE, .name = "s3c2410-ohci", }, };


    1)在内核初始化时kernel_init()->do_basic_setup()->driver_init()->platform_bus_init()初始化platform_bus(虚拟总线);

    2)设备注册的时候platform_device_register()->platform_device_add()->(pdev->dev.bus = &platform_bus_type)把设备挂在虚拟的platform bus下;

    3)驱动注册的时候platform_driver_register()->driver_register()->bus_add_driver()->driver_attach()->bus_for_each_dev(),对每个挂在虚拟的
    platform bus的设备作__driver_attach()->driver_probe_device(),判断drv->bus->match()是否存在并且是否执行成功,此时通过指针执行platform_match,
    比较strncmp(pdev->name, drv->name, BUS_ID_SIZE),如果相符就调用really_probe(实际就是执行的相应设备的platform_driver->probe(platform_device),
    注意platform_drv_probe的_dev参数是由bus_for_each_dev的next_device获得)开始真正的探测加载,如果probe成功则绑定该设备到该驱动。 当进入probe函数后,需要获取设备的资源信息,根据参数type所指定类型,例如IORESOURCE_MEM,来分别获取指定的资源。
    struct resource * platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num);当然,也可以固定资源类型,
    如获取资源中的中断号:struct int platform_get_irq(struct platform_device *dev, unsigned int num); probe函数一般完成硬件设备使能,struct resource的获取以及虚拟地址的动态映射和具体类型设备的注册(因为平台设备只是一种虚拟的设备类型);
    remove函数完成硬件设备的关闭,struct resource以及虚拟地址的动态映射的释放和具体类型设备的注销。只要和内核本身运行依赖性不大的外围设备
    ( 换句话说只要不在内核运行所需的一个最小系统之内的设备 ), 相对独立的拥有各自独自的资源 (addresses and IRQs) ,都可以用platform_driver 实现。
    如:lcd,usb,uart 等,都可以用platfrom_driver 写,而timer,irq等最小系统之内的设备则最好不用platfrom_driver 机制,实际上内核实现也是这样的。


    http://blog.csdn.net/zhandoushi1982/article/details/5130207

    http://blog.csdn.net/lichengtongxiazai/article/details/38941997    DT书写规范     

    http://www.right.com.cn/forum/thread-146260-1-1.html   DT(2) 

    http://blog.csdn.net/zengxianyang/article/details/50732929  DT驱动写法

    http://blog.csdn.net/21cnbao/article/details/8457546  DT宋宝华 

    http://www.cnblogs.com/dyllove98/archive/2013/07/03/3170178.html 获取DT资源

    http://blog.csdn.net/zqixiao_09/article/details/50888795      platform_device字符驱动

  • 相关阅读:
    BZOJ_1712_[Usaco2007 China]Summing Sums 加密_矩阵乘法
    BZOJ_2693_jzptab_莫比乌斯反演
    BZOJ_5296_[Cqoi2018]破解D-H协议_BSGS
    BZOJ_5301_[Cqoi2018]异或序列&&CF617E_莫队
    前端开发框架对比
    现在企业流行的java框架技术
    尼古拉斯·沃斯
    算法和流程图
    Java中DAO的实现
    java中的DAO设计模式
  • 原文地址:https://www.cnblogs.com/chencesc/p/6210754.html
Copyright © 2011-2022 走看看