zoukankan      html  css  js  c++  java
  • linux kernel 平台总线实例分析

    linux 平台总线的实现有三大块  , platform bus , platform device , platform drvice

    平台类型结构体:

     1                                                                                  
     2 /**                                                                             
     3  * struct bus_type - The bus type of the device                                 
     4  *                                                                              
     5  * @name:   The name of the bus.                                                
     6  * @bus_attrs:  Default attributes of the bus.                                  
     7  * @dev_attrs:  Default attributes of the devices on the bus.                   
     8  * @drv_attrs:  Default attributes of the device drivers on the bus.            
     9  * @match:  Called, perhaps multiple times, whenever a new device or driver     
    10  *      is added for this bus. It should return a nonzero value if the          
    11  *      given device can be handled by the given driver.                        
    12  * @uevent: Called when a device is added, removed, or a few other things       
    13  *      that generate uevents to add the environment variables.                 
    14  * @probe:  Called when a new device or driver add to this bus, and callback    
    15  *      the specific driver's probe to initial the matched device.              
    16  * @remove: Called when a device removed from this bus.                         
    17  * @shutdown:   Called at shut-down time to quiesce the device.                 
    18  * @suspend:    Called when a device on this bus wants to go to sleep mode.     
    19  * @resume: Called to bring a device on this bus out of sleep mode.             
    20  * @pm:     Power management operations of this bus, callback the specific      
    21  *      device driver's pm-ops.                                                
    22 * @p:      The private data of the driver core, only the driver core can       
    23  *      touch this.                                                             
    24  *                                                                              
    25  * A bus is a channel between the processor and one or more devices. For the    
    26  * purposes of the device model, all devices are connected via a bus, even if   
    27  * it is an internal, virtual, "platform" bus. Buses can plug into each other.  
    28  * A USB controller is usually a PCI device, for example. The device model      
    29  * represents the actual connections between buses and the devices they control.
    30  * A bus is represented by the bus_type structure. It contains the name, the    
    31  * default attributes, the bus' methods, PM operations, and the driver core's   
    32  * private data.                                                                
    33  */       
     1 struct bus_type {                                                               
     2     const char      *name;                                                      
     3     struct bus_attribute    *bus_attrs; // 总线属性                             
     4     struct device_attribute *dev_attrs; // 设备属性                             
     5     struct driver_attribute *drv_attrs; // 驱动性                                                                                                             
     6     int (*match)(struct device *dev, struct device_driver *drv); //匹配平台设备与平台驱动的函数
     7     int (*uevent)(struct device *dev, struct kobj_uevent_env *env);             
     8     int (*probe)(struct device *dev);                                           
     9     int (*remove)(struct device *dev);                                          
    10     void (*shutdown)(struct device *dev);                                       
    11                                                                                 
    12     int (*suspend)(struct device *dev, pm_message_t state);                     
    13     int (*resume)(struct device *dev);                                          
    14                                                                                 
    15     const struct dev_pm_ops *pm;                                                
    16                                                                                 
    17     struct subsys_private *p;                                                   
    18 };                                                                              

    参考: http://blog.chinaunix.net/uid-25622207-id-2778126.html

    在kernel中 , 首先是有platform bus被kernel 注册

    有以下流程:

    init/main.c

     1 static int __init kernel_init(void * unused)                                    
     2 {                                                                              
     3     ......
     4     do_basic_setup();
     5     ......
     6 }
     7 
     8 //再到
     9 static void __init do_basic_setup(void)                                         
    10 {                                                                               
    11     cpuset_init_smp();                                                          
    12     usermodehelper_init();                                                      
    13     init_tmpfs();                                                               
    14     driver_init();                                                              
    15     init_irq_proc();                                                            
    16     do_ctors();                                                                 
    17     do_initcalls();                                                             
    18 }                                                       

    再进 driver_init()

     1 void __init driver_init(void)                                                   
     2 {                                                                               
     3     /* These are the core pieces */                                             
     4     devtmpfs_init();                                                            
     5     devices_init();                                                             
     6     buses_init();                                                               
     7     classes_init();                                                             
     8     firmware_init();                                                            
     9     hypervisor_init();                                                          
    10                                                                                 
    11     /* These are also core pieces, but must come after the                      
    12      * core core pieces.                                                        
    13      */                                                                         
    14     platform_bus_init();            //平台总线初始化                                              
    15     system_bus_init();                                                          
    16     cpu_dev_init();                                                             
    17     memory_dev_init();                                                          
    18 }                                                 

    再进平台总线初始化

     1 struct device platform_bus = {                                                  
     2     .init_name  = "platform",                                                   
     3 };                                                                              
     4 EXPORT_SYMBOL_GPL(platform_bus);                                              
     5 //...
     6                                                                                 
     7 struct bus_type platform_bus_type = {                                           
     8     .name       = "platform",                                                   
     9     .dev_attrs  = platform_dev_attrs,                                           
    10     .match      = platform_match,                                               
    11     .uevent     = platform_uevent,                                              
    12     .pm     = &platform_dev_pm_ops,                                             
    13 };                                                                              
    14 EXPORT_SYMBOL_GPL(platform_bus_type);                           
    15 
    16 //...
    17 int __init platform_bus_init(void)                                              
    18 {                                                                               
    19     int error;                                                                  
    20                                                                                 
    21     early_platform_cleanup();                                                   
    22                                                                                 
    23     error = device_register(&platform_bus);  //将平台总线作为一个设备注册       
    24     if (error)                                                                  
    25         return error;                                                           
    26     error =  bus_register(&platform_bus_type); 
    27     if (error)                                                                  
    28         device_unregister(&platform_bus);                                       
    29     return error;                                                               
    30 }                                                             

    match 函数是等下匹配platform device 和 platform driver 的函数

     1 /**                                                                             
     2  * platform_match - bind platform device to platform driver.                    
     3  * @dev: device.                                                                
     4  * @drv: driver.                                                                
     5  *                                                                              
     6  * Platform device IDs are assumed to be encoded like this:                     
     7  * "<name><instance>", where <name> is a short description of the type of       
     8  * device, like "pci" or "floppy", and <instance> is the enumerated             
     9  * instance of the device, like '0' or '42'.  Driver IDs are simply             
    10  * "<name>".  So, extract the <name> from the platform_device structure,        
    11  * and compare it against the name of the driver. Return whether they match     
    12  * or not.                                                                      
    13  */                                                            
    14 
    15 static int platform_match(struct device *dev, struct device_driver *drv)        
    16 {                                                                               
    17     struct platform_device *pdev = to_platform_device(dev);                     
    18     struct platform_driver *pdrv = to_platform_driver(drv);                     
    19                                                                                 
    20     /* Attempt an OF style match first */                                       
    21     if (of_driver_match_device(dev, drv))                                       
    22         return 1;                                                               
    23                                                                                 
    24     /* Then try to match against the id table */                                
    25     if (pdrv->id_table)                                                         
    26         return platform_match_id(pdrv->id_table, pdev) != NULL;                 
    27                                                                                 
    28     /* fall-back to driver name match */                                        
    29     return (strcmp(pdev->name, drv->name) == 0);                                
    30 }                                                       
     //通过id_table 来匹配
    1 static const struct platform_device_id *platform_match_id( 2 const struct platform_device_id *id, 3 struct platform_device *pdev) 4 { 5 while (id->name[0]) { 6 if (strcmp(pdev->name, id->name) == 0) { 7 pdev->id_entry = id; 8 return id; 9 } 10 id++; 11 } 12 return NULL; 13 }
    1 int device_register(struct device *dev)                                         
    2 {                                                                               
    3     device_initialize(dev);                                                     
    4     return device_add(dev);                                                     
    5 }                                                                               

    此时platform bus 已经作为一个设备挂到内核上

     

    看完平台总线, 下面看平台设备的注册流程:

    还是得把一开始的platform device 结构体放到这里来:

     1                                                                                 
     2 struct platform_device {                                                        
     3     const char  * name;             //平台设备名字                              
     4     int     id;                                                                 
     5     struct device   dev;            //设备结构体                                          
     6     u32     num_resources;          //资源个数                                  
     7     struct resource * resource;     //资源                                      
     8                                                                                 
     9     const struct platform_device_id *id_entry;                                  
    10                                                                                 
    11     /* MFD cell pointer */                                                      
    12     struct mfd_cell *mfd_cell;                                                  
    13                                                                                 
    14     /* arch specific additions */                                               
    15     struct pdev_archdata    archdata;                                           
    16 };                                                                              
    17                                                                                 
    18 #define platform_get_device_id(pdev)    ((pdev)->id_entry)                      
    19 //通过device 找到对应的platform_device 结构体                                   
    20 #define to_platform_device(x) container_of((x), struct platform_device, dev)   
     
    
     其实这里边还有个设备结构体 , 他是依附在平台设备里面
    
     1 /**                                                                             
     2  * struct device - The basic device structure                                   
     3  * @parent: The device's "parent" device, the device to which it is attached.   
     4  *      In most cases, a parent device is some sort of bus or host              
     5  *      controller. If parent is NULL, the device, is a top-level device,       
     6  *      which is not usually what you want.                                     
     7  * @p:      Holds the private data of the driver core portions of the device.   
     8  *      See the comment of the struct device_private for detail.                
     9  * @kobj:   A top-level, abstract class from which other classes are derived.   
    10  * @init_name:  Initial name of the device.                                     
    11  * @type:   The type of device.                                                 
    12  *      This identifies the device type and carries type-specific               
    13  *      information.                                                            
    14  * @mutex:  Mutex to synchronize calls to its driver.                           
    15  * @bus:    Type of bus device is on.                                           
    16  * @driver: Which driver has allocated this                                     
    17  * @platform_data: Platform data specific to the device.                        
    18  *      Example: For devices on custom boards, as typical of embedded           
    19  *      and SOC based hardware, Linux often uses platform_data to point         
    20  *      to board-specific structures describing devices and how they            
    21  *      are wired.  That can include what ports are available, chip             
    22  *      variants, which GPIO pins act in what additional roles, and so   
    23  *      on.  This shrinks the "Board Support Packages" (BSPs) and               
    24  *      minimizes board-specific #ifdefs in drivers.                            
    25  * @power:  For device power management.                                        
    26  *      See Documentation/power/devices.txt for details.                        
    27  * @pwr_domain: Provide callbacks that are executed during system suspend,      
    28  *      hibernation, system resume and during runtime PM transitions            
    29  *      along with subsystem-level and driver-level callbacks.                  
    30  * @numa_node:  NUMA node this device is close to.                              
    31  * @dma_mask:   Dma mask (if dma'ble device).                                   
    32  * @coherent_dma_mask: Like dma_mask, but for alloc_coherent mapping as not all 
    33  *      hardware supports 64-bit addresses for consistent allocations           
    34  *      such descriptors.                                                       
    35  * @dma_parms:  A low level driver may set these to teach IOMMU code about      
    36  *      segment limitations.                                                    
    37  * @dma_pools:  Dma pools (if dma'ble device).                                  
    38  * @dma_mem:    Internal for coherent mem override.                             
    39  * @archdata:   For arch-specific additions.                                    
    40  * @of_node:    Associated device tree node.                                    
    41  * @devt:   For creating the sysfs "dev".                                       
    42  * @devres_lock: Spinlock to protect the resource of the device.      
    43  * @devres_head: The resources list of the device.                              
    44  * @knode_class: The node used to add the device to the class list.             
    45  * @class:  The class of the device.                                            
    46  * @groups: Optional attribute groups.                                          
    47  * @release:    Callback to free the device after all references have           
    48  *      gone away. This should be set by the allocator of the                   
    49  *      device (i.e. the bus driver that discovered the device).                
    50  *                                                                              
    51  * At the lowest level, every device in a Linux system is represented by an     
    52  * instance of struct device. The device structure contains the information     
    53  * that the device model core needs to model the system. Most subsystems,       
    54  * however, track additional information about the devices they host. As a      
    55  * result, it is rare for devices to be represented by bare device structures;  
    56  * instead, that structure, like kobject structures, is usually embedded within 
    57  * a higher-level representation of the device.                                 
    58  */                                                       
    
     1 struct device {                                                                 
     2     struct device       *parent;     // 设备的父类                              
     3                                                                                 
     4     struct device_private   *p;       //设备的私有数据                                          
     5                                                                                 
     6     struct kobject kobj;                                                        
     7     const char      *init_name; /* initial name of the device */                
     8     const struct device_type *type;                                             
     9                                                                                 
    10     struct mutex        mutex;  /* mutex to synchronize calls to                
    11                      * its driver.                                              
    12                      */                                                         
    13     //表示该设备是属于哪一条总线                                                
    14     struct bus_type *bus;       /* type of bus device is on */                  
    15     struct device_driver *driver;   /* which driver has allocated this          
    16         device */ // 哪个驱动调用了这个设备                                     
    17     void        *platform_data; /* Platform specific data, device               
    18                        core doesn't touch it ***********/                                 
    19     struct dev_pm_info  power;                                                  
    20     struct dev_power_domain *pwr_domain;                                       
    21                                                                                 
    22 #ifdef CONFIG_NUMA                                                              
    23     int     numa_node;  /* NUMA node this device is close to */                 
    24 #endif                                                                          
    25     u64     *dma_mask;  /* dma mask (if dma'able device) */                     
    26     u64     coherent_dma_mask;/* Like dma_mask, but for                         
    27                          alloc_coherent mappings as                             
    28                          not all hardware supports                              
    29                          64 bit addresses for consistent                        
    30                          allocations such descriptors. */                       
    31                                                                                 
    32     struct device_dma_parameters *dma_parms;                                    
    33                                                                                 
    34     struct list_head    dma_pools;  /* dma pools (if dma'ble) */                
    35                                                                                 
    36     struct dma_coherent_mem *dma_mem; /* internal for coherent mem              
    37                          override */                                            
    38     /* arch specific additions */                                               
    39     struct dev_archdata archdata;                                               
    40                                                                                 
    41     struct device_node  *of_node; /* associated device tree node */    
    42                                                                                 
    43     dev_t           devt;   /* dev_t, creates the sysfs "dev" */ //主次设备号的>结合体
    44                                                                                 
    45     spinlock_t      devres_lock;                                                
    46     struct list_head    devres_head;                                            
    47                                                                                 
    48     struct klist_node   knode_class;                                            
    49     struct class        *class;                                                 
    50     const struct attribute_group **groups;  /* optional groups */               
    51                                                                                 
    52     void    (*release)(struct device *dev);                                     
    53 };                                          
    
     
    1 //平台设备注册函数                                                              
    2 extern int platform_device_register(struct platform_device *);                  
    3 extern void platform_device_unregister(struct platform_device *);               
    4 //平台设备解注册函数                                                            

    这两个函数对外发布

    i2c 设备就用到了这个 函数进行 platform device 的 register

    在arch/arm/mach-mx6/board-mx6q_sabresd.c 中

    1 MACHINE_START(MX6Q_SABRESD, "Freescale i.MX 6Quad/DualLite/Solo Sabre-SD Board")    /* Maintainer: Freescale Semiconductor, Inc. */                             
    2     .boot_params = MX6_PHYS_OFFSET + 0x100,                                     
    3     .fixup = fixup_mxc_board,                                                   
    4     .map_io = mx6_map_io,                                                       
    5     .init_irq = mx6_init_irq,                                                   
    6     .init_machine = mx6_sabresd_board_init,  // 板级的初始化                    
    7     .timer = &mx6_sabresd_timer,            // 时钟的初始化                     
    8     .reserve = mx6q_sabresd_reserve,                                            
    9 MACHINE_END                                                                     

    时钟的话跟过去得到 i2c 的   CLK  的速度是400KB/s

    在mx6_sabresd_board_init 中

    平台设备内设备的平台数据进行赋值

    1 static struct i2c_gpio_platform_data i2c_bus_gpio_data = {                      
    2     .sda_pin = SABRESD_I2C4_SDA_GPIO,                                           
    3     .scl_pin = SABRESD_I2C4_SCL_GPIO,                                           
    4     .udelay  = 10,      //10Khz                                                 
    5     .timeout = 500,                                                             
    6     //.sda_is_open_drain = 1,       //在当前板子上不能加                        
    7     //.scl_is_open_drain = 1,       //在当前板子上不能加                        
    8 };                                                                 

    平台设备结构体的赋值

    1 static struct platform_device i2c_bus_gpio_device = {                           
    2     .name  = "i2c-gpio",  //这个名字是必须这样,主要是为了和i2c-gpio驱动对应    
    3     //由于板子已经用掉了0,1,2号,这里使用3                                      
    4     .id  = 3, /* bus have 0,1,2, so start at 3 */                               
    5     .dev = {                                                                    
    6         .platform_data = &i2c_bus_gpio_data,                                    
    7     }                                                                           
    8 };                                                                              

    板级的初始化:

     1 static void __init mx6_sabresd_board_init(void)                                 
     2 {                                                                               
     3 
     4     //。。。。。。
     5 
     6     /**                                                                         
     7       * register gpio i2c bus                   write by zengjf                 
     8       * 注册i2c-gpio设备,相当于注册一个I2C控制器                               
     9       */                                                                        
    10     platform_device_register(&i2c_bus_gpio_device);                             
    11                                                                                 
    12     i2c_register_board_info(0, mxc_i2c0_board_info,                             
    13             ARRAY_SIZE(mxc_i2c0_board_info));                                   
    14     i2c_register_board_info(1, mxc_i2c1_board_info,                             
    15             ARRAY_SIZE(mxc_i2c1_board_info));                                   
    16     i2c_register_board_info(2, mxc_i2c2_board_info,                             
    17             ARRAY_SIZE(mxc_i2c2_board_info));                                   
    18      /**                                                                        
    19       * register gpio i2c device                write by zengjf                 
    20       * 在I2C控制器3上注册I2C设备,这里的控制器3就是前面注册的I2C控制器,       
    21       * 主要是因为前面注册的I2C控制器的id是3                                    
    22       */                                                                        
    23      i2c_register_board_info(3, gpio_i2c_devices, ARRAY_SIZE(gpio_i2c_devices));
    24 
    25     //。。。。。。
    26 
    27 }

    在mx6这块板子身上 , i2c 0 , 1 , 2 是比较正常的i2c 总线, 但是i2c 3 是用的两个GPIO口模拟的 i2c 的SCL和 SDA线 

    下面 , 跟进

    1    platform_device_register(&i2c_bus_gpio_device);       

    /drivers/base/platform.c

     1 /**                                                                             
     2  * platform_device_register - add a platform-level device                       
     3  * @pdev: platform device we're adding                                          
     4  */                                                                             
     5 int platform_device_register(struct platform_device *pdev)                      
     6 {                                                                               
     7     device_initialize(&pdev->dev);         //初始化设备                                       
     8     return platform_device_add(pdev);      //平台设备添加                                     
     9 }                                                                               
    10 EXPORT_SYMBOL_GPL(platform_device_register);                                   

     跟进 platform_device_add(pdev)

     1 /**                                                                             
     2  * platform_device_add - add a platform device to device hierarchy              
     3  * @pdev: platform device we're adding                                          
     4  *                                                                              
     5  * This is part 2 of platform_device_register(), though may be called           
     6  * separately _iff_ pdev was allocated by platform_device_alloc().              
     7  */                                                                             
     8 int platform_device_add(struct platform_device *pdev)                           
     9 {                                                                               
    10     int i, ret = 0;                                                             
    11                                                                                 
    12     if (!pdev)                                                                  
    13         return -EINVAL;                                                         
    14                                                                                 
    15     if (!pdev->dev.parent)                                                      
    16         pdev->dev.parent = &platform_bus;    //属于平台总线,                    
    17                                                                                 
    18     pdev->dev.bus = &platform_bus_type;         // 在platform_bus_init()的时候已经注册了平台总线类型                         
    19                                                                                 
    20     if (pdev->id != -1)                                                        
    21         dev_set_name(&pdev->dev, "%s.%d", pdev->name,  pdev->id);   //pdev->dev 只有一个platform_data , pdev->name == i2c-gpio , pdev->id == 3      
    22     else                                                                        
    23         dev_set_name(&pdev->dev, "%s", pdev->name);                             
    24                                                                                 
    25     for (i = 0; i < pdev->num_resources; i++) {                                 
    26         struct resource *p, *r = &pdev->resource[i];                            
    27                                                                                 
    28         if (r->name == NULL)                                                    
    29             r->name = dev_name(&pdev->dev);                                     
    30                                                                                 
    31         p = r->parent;                                                          
    32         if (!p) {                                                               
    33             if (resource_type(r) == IORESOURCE_MEM)                             
    34                 p = &iomem_resource;                                            
    35             else if (resource_type(r) == IORESOURCE_IO)                         
    36                 p = &ioport_resource;                                           
    37         }                                                                       
    38                                                                                 
    39         if (p && insert_resource(p, r)) {                                       
    40             printk(KERN_ERR                                                     
    41                    "%s: failed to claim resource %d
    ",                        
    42                    dev_name(&pdev->dev), i);                                    
    43             ret = -EBUSY;                                                       
    44             goto failed;                                                        
    45         }                                                                       
    46     }                                                                           
    47                                                                                 
    48     pr_debug("Registering platform device '%s'. Parent at %s
    ",                
    49          dev_name(&pdev->dev), dev_name(pdev->dev.parent));                     
    50                                                                                 
    51     ret = device_add(&pdev->dev);         //最终通过这里将设备挂到设备链表上                                     
    52     if (ret == 0)                                                               
    53         return ret;                                                             
    54                                                                                 
    55  failed:                                                                        
    56     while (--i >= 0) {                                                          
    57         struct resource *r = &pdev->resource[i];                                
    58         unsigned long type = resource_type(r);                                  
    59                                                                                 
    60         if (type == IORESOURCE_MEM || type == IORESOURCE_IO)                    
    61             release_resource(r);                                                
    62     }                                                                          
    63                                                                                 
    64     return ret;                                                                 
    65 }                                                                               
    66 EXPORT_SYMBOL_GPL(platform_device_add);      


    最终 ,通过上面那个函数 注册一个平台设备 , 我们自己也可以利用这个函数(platform_device_add)   去注册一个我们自己的平台设备 与我们自己本身的平台设备的驱动相匹配 

    相对应的 , 有平台设备的注册就必然有平台设备的解除注册

     1 /**                                                                             
     2  * platform_device_unregister - unregister a platform-level device              
     3  * @pdev: platform device we're unregistering                                   
     4  *                                                                              
     5  * Unregistration is done in 2 steps. First we release all resources            
     6  * and remove it from the subsystem, then we drop reference count by            
     7  * calling platform_device_put().                                               
     8  */                                                                             
     9 void platform_device_unregister(struct platform_device *pdev)                   
    10 {                                                                               
    11     platform_device_del(pdev);                                                  
    12     platform_device_put(pdev);                                                  
    13 }                                                                               
    14 EXPORT_SYMBOL_GPL(platform_device_unregister);                                 

    从而得到我们平台设备的接触注册是调用了platform_device_del()

     1 /**                                                                             
     2  * platform_device_del - remove a platform-level device                         
     3  * @pdev: platform device we're removing                                        
     4  *                                                                              
     5  * Note that this function will also release all memory- and port-based         
     6  * resources owned by the device (@dev->resource).  This function must          
     7  * _only_ be externally called in error cases.  All other usage is a bug.       
     8  */                                                                             
     9 void platform_device_del(struct platform_device *pdev)                          
    10 {                                                                               
    11     int i;                                                                      
    12                                                                                 
    13     if (pdev) {                                                                 
    14         device_del(&pdev->dev);             //对应的是device_add , 该函数是设备删除                                    
    15                                                                                 
    16         for (i = 0; i < pdev->num_resources; i++) {                             
    17             struct resource *r = &pdev->resource[i];                            
    18             unsigned long type = resource_type(r);                              
    19                                                                                 
    20             if (type == IORESOURCE_MEM || type == IORESOURCE_IO)                
    21                 release_resource(r);                                          
    22         }                                                                       
    23     }                                                                           
    24 }                                                                               
    25 EXPORT_SYMBOL_GPL(platform_device_del);     

    我们可以用这个函数对平台设备解除注册

    下面就分析一下 , i2c3 总线上 eeprom 这个设备驱动 , 并分析他是怎么通过一系列相关的匹配 将平台总线 , 平台设备, 平台设备驱动相关联(匹配)。

    老样子 , 先上两个结构体

    平台驱动结构体:

    1 struct platform_driver {                                                        
    2     int (*probe)(struct platform_device *);          //这个函数是一个真正的入口函数 , 等下会分析                          
    3     int (*remove)(struct platform_device *);                                    
    4     void (*shutdown)(struct platform_device *);                                 
    5     int (*suspend)(struct platform_device *, pm_message_t state);               
    6     int (*resume)(struct platform_device *);                                    
    7     struct device_driver driver;                       //设备驱动结构体                         
    8     const struct platform_device_id *id_table;         //平台设备id表                         
    9 };                                                             

     设备驱动结构体:

     1                                                                                 
     2 /**                                                                             
     3  * struct device_driver - The basic device driver structure                     
     4  * @name:   Name of the device driver.                                          
     5  * @bus:    The bus which the device of this driver belongs to.                 
     6  * @owner:  The module owner.                                                   
     7  * @mod_name:   Used for built-in modules.                                      
     8  * @suppress_bind_attrs: Disables bind/unbind via sysfs.                        
     9  * @of_match_table: The open firmware table.                                    
    10  * @probe:  Called to query the existence of a specific device,                 
    11  *      whether this driver can work with it, and bind the driver               
    12  *      to a specific device.                                                   
    13  * @remove: Called when the device is removed from the system to                
    14  *      unbind a device from this driver.                                       
    15  * @shutdown:   Called at shut-down time to quiesce the device.                 
    16  * @suspend:    Called to put the device to sleep mode. Usually to a            
    17  *      low power state.                                                        
    18  * @resume: Called to bring a device from sleep mode.                           
    19  * @groups: Default attributes that get created by the driver core              
    20  *      automatically.                                                  
    21  * @pm:     Power management operations of the device which matched             
    22  *      this driver.                                                            
    23  * @p:      Driver core's private data, no one other than the driver            
    24  *      core can touch this.                                                    
    25  *                                                                              
    26  * The device driver-model tracks all of the drivers known to the system.       
    27  * The main reason for this tracking is to enable the driver core to match      
    28  * up drivers with new devices. Once drivers are known objects within the       
    29  * system, however, a number of other things become possible. Device drivers    
    30  * can export information and configuration variables that are independent      
    31  * of any specific device.                                                      
    32  */                                                                            
     1 struct device_driver {                                                          
     2     const char      *name;     /* 设备驱动的名字 */                             
     3     struct bus_type     *bus;  /* belong which bus  (chenfl)*/                  
     4                                                                                 
     5     struct module       *owner;                                                 
     6     const char      *mod_name;  /* used for built-in modules */                 
     7                                                                                 
     8     bool suppress_bind_attrs;   /* disables bind/unbind via sysfs */            
     9                                                                                 
    10     const struct of_device_id   *of_match_table;                                
    11                                                                                 
    12     int (*probe) (struct device *dev);                                          
    13     int (*remove) (struct device *dev);                                         
    14     void (*shutdown) (struct device *dev);                                      
    15     int (*suspend) (struct device *dev, pm_message_t state);                    
    16     int (*resume) (struct device *dev);                                         
    17     const struct attribute_group **groups;                                      
    18                                                                                 
    19     const struct dev_pm_ops *pm;                                                
    20                                                                                 
    21                                                                                 
    22     struct driver_private *p;                                                   
    23 };                                                                             

    再介绍一个两个函数:

    1 //平台设备驱动的注册函数                                                        
    2 extern int platform_driver_register(struct platform_driver *);                  
    3 extern void platform_driver_unregister(struct platform_driver *);               
    4 //平台设备驱动解除注册函数

    等下会对这两个函数进行分析

    了解完这两个结构体后来跟一个epprom 这个设备的驱动

    如果是借鉴的就随意找一个平台设备驱动与之同理

    drivers/misc/eeprom/at24.c:

    1 static struct i2c_driver at24_driver = {                                        
    2     .driver = {                                                                 
    3         .name = "at24",                                                         
    4         .owner = THIS_MODULE,                                                   
    5     },                                                                          
    6     .probe = at24_probe,                                                        
    7     .remove = __devexit_p(at24_remove),                                         
    8     .id_table = at24_ids,                                                       
    9 };                                                                             
     1 static int __init at24_init(void)                                               
     2 {                                                                               
     3     if (!io_limit) {                                                            
     4         pr_err("at24: io_limit must not be 0!
    ");                              
     5         return -EINVAL;                                                         
     6     }                                                                           
     7                                                                                 
     8     io_limit = rounddown_pow_of_two(io_limit);                                  
     9     return i2c_add_driver(&at24_driver);                                        
    10 }                                                                               
    11 module_init(at24_init);                                      
    1 static inline int i2c_add_driver(struct i2c_driver *driver)                     
    2 {                                                                               
    3     return i2c_register_driver(THIS_MODULE, driver);          
    4 }
     1                                                                                 
     2 struct bus_type i2c_bus_type = {                                                
     3     .name       = "i2c",                                                        
     4     .match      = i2c_device_match,                                             
     5     .probe      = i2c_device_probe,                                             
     6     .remove     = i2c_device_remove,                                            
     7     .shutdown   = i2c_device_shutdown,                                          
     8     .pm     = &i2c_device_pm_ops,                                               
     9 };                                                                              
    10 EXPORT_SYMBOL_GPL(i2c_bus_type);                      
     1 /*                                                                              
     2  * An i2c_driver is used with one or more i2c_client (device) nodes to access   
     3  * i2c slave chips, on a bus instance associated with some i2c_adapter.         
     4  */                                                                             
     5                                                                                 
     6 int i2c_register_driver(struct module *owner, struct i2c_driver *driver)        
     7 {                                                                               
     8     int res;                                                                    
     9                                                                                 
    10     /* Can't register until after driver model init */                          
    11     if (unlikely(WARN_ON(!i2c_bus_type.p)))                                     
    12         return -EAGAIN;                                                         
    13                                                                                 
    14     /* add the driver to the list of i2c drivers in the driver core */          
    15     driver->driver.owner = owner;                                               
    16     driver->driver.bus = &i2c_bus_type;                                         
    17                                                                                 
    18     /* When registration returns, the driver core                               
    19      * will have called probe() for all matching-but-unbound devices.     
    20     *///这里边有一个匹配成功并执行probe的过程                                                                        
    21     res = driver_register(&driver->driver);         //drvier->driver == {.name =    .name = "at24", .owner = THIS_MODULE, }  
                                                .owner = owner ,
                                                .bus = &i2c_bus_type }
    22 if (res) 23 return res; 24 25 /* Drivers should switch to dev_pm_ops instead. */ 26 if (driver->suspend) 27 pr_warn("i2c-core: driver [%s] using legacy suspend method ", 28 driver->driver.name); 29 if (driver->resume) 30 pr_warn("i2c-core: driver [%s] using legacy resume method ", 31 driver->driver.name); 32 33 pr_debug("i2c-core: driver [%s] registered ", driver->driver.name); 34 35 INIT_LIST_HEAD(&driver->clients); 36 /* Walk the adapters that are already present */ 37 i2c_for_each_dev(driver, __process_new_driver); 38 39 return 0; 40 } 41 EXPORT_SYMBOL(i2c_register_driver);

    再进driver_register(struct device_driver *drv)

     1 /**                                                                             
     2  * driver_register - register driver with bus                                   
     3  * @drv: driver to register                                                     
     4  *                                                                              
     5  * We pass off most of the work to the bus_add_driver() call,                   
     6  * since most of the things we have to do deal with the bus                     
     7  * structures.                                                                  
     8  */                                                                             
     9 int driver_register(struct device_driver *drv)                                  
    10 {                                                                               
    11     int ret;                                                                    
    12     struct device_driver *other;                                                
    13                                                                                 
    14     BUG_ON(!drv->bus->p);                                                       
    15                                                                                 
    16     if ((drv->bus->probe && drv->probe) ||                                      
    17         (drv->bus->remove && drv->remove) ||                                    
    18         (drv->bus->shutdown && drv->shutdown))                                  
    19         printk(KERN_WARNING "Driver '%s' needs updating - please use "          
    20             "bus_type methods
    ", drv->name);                                   
    21                                                                                 
    22     other = driver_find(drv->name, drv->bus);                     
    23     if (other) {                                                                
    24         put_driver(other);                                                      
    25         printk(KERN_ERR "Error: Driver '%s' is already registered, "            
    26             "aborting...
    ", drv->name);                                        
    27         return -EBUSY;                                                          
    28     }                                                                           
    29                                                                                 
    30     ret = bus_add_driver(drv);      //再进!!!                                              
    31     if (ret)                                                                    
    32         return ret;                                                             
    33     ret = driver_add_groups(drv, drv->groups);                                  
    34     if (ret)                                                                    
    35         bus_remove_driver(drv);                                                 
    36     return ret;                                                                 
    37 }                                                                               
    38 EXPORT_SYMBOL_GPL(driver_register);                                             
    39                                                         

    再进bus_add_driver(drv)

     1 /**                                                                             
     2  * bus_add_driver - Add a driver to the bus.                                    
     3  * @drv: driver.                                                                
     4  */                                                                             
     5 int bus_add_driver(struct device_driver *drv)                                   
     6 {                                                                               
     7     struct bus_type *bus;                                                       
     8     struct driver_private *priv;                                                
     9     int error = 0;                                                              
    10                                                                                 
    11     bus = bus_get(drv->bus);                                                    
    12     if (!bus)                                                                   
    13         return -EINVAL;                                                         
    14                                                                                 
    15     pr_debug("bus: '%s': add driver %s
    ", bus->name, drv->name);               
    16                                                                                 
    17     priv = kzalloc(sizeof(*priv), GFP_KERNEL);                                  
    18     if (!priv) {                                                                
    19         error = -ENOMEM;                                                        
    20         goto out_put_bus;                                                       
    21     }                                                                           
    22     klist_init(&priv->klist_devices, NULL, NULL);                           
    23     //初始化设备链表,每一个与该驱动匹配的device都会添加到该链表下              
    24     priv->driver = drv;                                                         
    25     drv->p = priv;                                                              
    26     priv->kobj.kset = bus->p->drivers_kset;                                     
    27     //指向该驱动所属的kset                                                      
    28     error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,              
    29                      "%s", drv->name);                                          
    30     //初始化kobject 并将kobject添加到其对应的kset 集合中                        
    31     if (error)                                                                  
    32         goto out_unregister;                                                    
    33                                                                                 
    34     if (drv->bus->p->drivers_autoprobe) {                                       
    35         error = driver_attach(drv);            // 这里是即将要 绑定设备 与 驱动 并调用probe 地方                                 
    36         if (error)                                                              
    37             goto out_unregister;                                                
    38     }                                                                           
    39     klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);                   
    40     module_add_driver(drv->owner, drv);                                         
    41                                                                                 
    42     error = driver_create_file(drv, &driver_attr_uevent);                       
    43     if (error) {                                                                
    44         printk(KERN_ERR "%s: uevent attr (%s) failed
    ",                        
    45             __func__, drv->name);                                          
    46     }                                                                           
    47     error = driver_add_attrs(bus, drv);                                         
    48     if (error) {                                                                
    49         /* How the hell do we get out of this pickle? Give up */                
    50         printk(KERN_ERR "%s: driver_add_attrs(%s) failed
    ",                    
    51             __func__, drv->name);                                               
    52     }                                                                           
    53                                                                                 
    54     if (!drv->suppress_bind_attrs) {                                            
    55         error = add_bind_files(drv);                                            
    56         if (error) {                                                            
    57             /* Ditto */                                                         
    58             printk(KERN_ERR "%s: add_bind_files(%s) failed
    ",                  
    59                 __func__, drv->name);                                           
    60         }                                                                       
    61     }                                                                           
    62                                                                                 
    63     kobject_uevent(&priv->kobj, KOBJ_ADD);                                      
    64     return 0;                                                                   
    65                                                                                                                                    
    66 out_unregister:                                                                 
    67     kobject_put(&priv->kobj);                                                   
    68     kfree(drv->p);                                                              
    69     drv->p = NULL;                                                              
    70 out_put_bus:                                                                    
    71     bus_put(bus);                                                               
    72     return error;                                                               
    73 }                       
     1 /**                                                                             
     2  * driver_attach - try to bind driver to devices.                               
     3  * @drv: driver.                                                                
     4  *                                                                              
     5  * Walk the list of devices that the bus has on it and try to                   
     6  * match the driver with each one.  If driver_probe_device()                    
     7  * returns 0 and the @dev->driver is set, we've found a                         
     8  * compatible pair.                                                             
     9  */                                                                             
    10 int driver_attach(struct device_driver *drv)                                    
    11 {                                                                               
    12     return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);              
    13     // __将driver_atttach 传去进                                                
    14     //将每一个查找得到的device进行驱动匹配                                      
    15 }                                                                               
    16 EXPORT_SYMBOL_GPL(driver_attach);                                
     1 /**                                                                             
     2  * bus_for_each_dev - device iterator.                                          
     3  * @bus: bus type.                                                              
     4  * @start: device to start iterating from.                                      
     5  * @data: data for the callback.                                                
     6  * @fn: function to be called for each device.                                  
     7  *                                                                              
     8  * Iterate over @bus's list of devices, and call @fn for each,                  
     9  * passing it @data. If @start is not NULL, we use that device to               
    10  * begin iterating from.                                                        
    11  *                                                                              
    12  * We check the return of @fn each time. If it returns anything                 
    13  * other than 0, we break out and return that value.                            
    14  *                                                                              
    15  * NOTE: The device that returns a non-zero value is not retained               
    16  * in any way, nor is its refcount incremented. If the caller needs             
    17  * to retain this data, it should do so, and increment the reference            
    18  * count in the supplied callback.                                              
    19  */                                                 
    20 int bus_for_each_dev(struct bus_type *bus, struct device *start,                
    21              void *data, int (*fn)(struct device *, void *))                    
    22 {                                                                               
    23     struct klist_iter i;                                                        
    24     struct device *dev;                                                         
    25     int error = 0;                                                              
    26                                                                                 
    27     if (!bus)                                                                   
    28         return -EINVAL;                                                         
    29                                                                                 
    30     klist_iter_init_node(&bus->p->klist_devices, &i,                            
    31                  (start ? &start->p->knode_bus : NULL));                        
    32     while ((dev = next_device(&i)) && !error)                                   
    33         error = fn(dev, data);                       // 就是这个东西!!!                          
    34     klist_iter_exit(&i);                                                        
    35     return error;                                                               
    36 }                                                                               
    37 EXPORT_SYMBOL_GPL(bus_for_each_dev);                        

    这里边 , 调用了fn这个函数 , fn 就是上面传进去的__driver_attach 函数

    然后 , 便有了

     1 static int __driver_attach(struct device *dev, void *data)                      
     2 {                                                                               
     3     struct device_driver *drv = data;                                           
     4                                                                                 
     5     /*                                                                          
     6      * Lock device and try to bind to it. We drop the error                     
     7      * here and always return 0, because we need to keep trying                 
     8      * to bind to devices and some drivers will return an error                 
     9      * simply if it didn't support the device.                                  
    10      *                                                                          
    11      * driver_probe_device() will spit a warning if there                       
    12      * is an error.                                                             
    13      */                                                                         
    14                                                                                 
    15     if (!driver_match_device(drv, dev))                                         
    16         return 0;                                                               
    17                                                                                 
    18     if (dev->parent)    /* Needed for USB */                                    
    19         device_lock(dev->parent);                                               
    20     device_lock(dev);                                               
    21     if (!dev->driver)                                                           
    22         driver_probe_device(drv, dev);              //如果此时设备上所挂的驱动为空 , 就进去                            
    23     device_unlock(dev);                                                         
    24     if (dev->parent)                                                            
    25         device_unlock(dev->parent);                                             
    26                                                                                 
    27     return 0;                                                                   
    28 }                      

    然后就有了

     1 /**                                                                             
     2  * driver_probe_device - attempt to bind device & driver together               
     3  * @drv: driver to bind a device to                                             
     4  * @dev: device to try to bind to the driver                                    
     5  *                                                                              
     6  * This function returns -ENODEV if the device is not registered,               
     7  * 1 if the device is bound successfully and 0 otherwise.                       
     8  *                                                                              
     9  * This function must be called with @dev lock held.  When called for a         
    10  * USB interface, @dev->parent lock must be held as well.                       
    11  */                                                                
    12 int driver_probe_device(struct device_driver *drv, struct device *dev)          
    13 {                                                                               
    14     int ret = 0;                                                                
    15                                                                                 
    16     if (!device_is_registered(dev))                                             
    17         return -ENODEV;                                                         
    18                                                                                 
    19     pr_debug("bus: '%s': %s: matched device %s with driver %s
    ",               
    20          drv->bus->name, __func__, dev_name(dev), drv->name);                   
    21                                                                                 
    22     pm_runtime_get_noresume(dev);                                               
    23     pm_runtime_barrier(dev);                                                    
    24     ret = really_probe(dev, drv);                //这里!!!                               
    25     pm_runtime_put_sync(dev);                                                   
    26                                                                                 
    27     return ret;                                                                 
    28 }                                         

    bind device and driver , run probe

     1 static int really_probe(struct device *dev, struct device_driver *drv)          
     2 {                                                                               
     3     int ret = 0;                                                                
     4                                                                                 
     5     atomic_inc(&probe_count);                                                   
     6     pr_debug("bus: '%s': %s: probing driver %s with device %s
    ",               
     7          drv->bus->name, __func__, drv->name, dev_name(dev));                   
     8     WARN_ON(!list_empty(&dev->devres_head));                                    
     9                                                                                 
    10     dev->driver = drv;            //设备上的驱动设置为driver                    
    11     if (driver_sysfs_add(dev)) {                                                
    12         printk(KERN_ERR "%s: driver_sysfs_add(%s) failed
    ",                    
    13             __func__, dev_name(dev));                                           
    14         goto probe_failed;                                                      
    15     }                                                                           
    16                                                                                 
    17     if (dev->bus->probe) {                                                      
    18         ret = dev->bus->probe(dev);   //如果总线上有probe , 就运行这个   
    19         if (ret)                                                                
    20             goto probe_failed;                                                  
    21     } else if (drv->probe) {                                         
    22         ret = drv->probe(dev);           //这里边在driver 注册的时候 , 已经给i2c_driver 里面的driver 结构体里边的bus 进行初始化赋值  
    23         if (ret)                                                                
    24             goto probe_failed;                                                  
    25     }                                                                           
    26                                                                                 
    27     driver_bound(dev);                                                          
    28     ret = 1;                                                                    
    29     pr_debug("bus: '%s': %s: bound device %s to driver %s
    ",                   
    30          drv->bus->name, __func__, dev_name(dev), drv->name);                   
    31     goto done;                                                                  
    32                                                                                 
    33 probe_failed:                                                                   
    34     devres_release_all(dev);                                                    
    35     driver_sysfs_remove(dev);                          
    36     dev->driver = NULL;                                                         
    37                                                                                 
    38     if (ret != -ENODEV && ret != -ENXIO) {                                      
    39         /* driver matched but the probe failed */                               
    40         printk(KERN_WARNING                                                     
    41                "%s: probe of %s failed with error %d
    ",                        
    42                drv->name, dev_name(dev), ret);                                  
    43     }                                                                           
    44     /*                                                                          
    45      * Ignore errors returned by ->probe so that the next driver can try        
    46      * its luck.                                                                
    47      */                                                                         
    48     ret = 0;                                                                    
    49 done:                                                                           
    50     atomic_dec(&probe_count);                                                   
    51     wake_up(&probe_waitqueue);                                                  
    52     return ret;                                                                 
    53 }                         

    上面22 行 , 有如下分析代码:

    1 struct bus_type i2c_bus_type = {                                                
    2     .name       = "i2c",                                                        
    3     .match      = i2c_device_match,                                             
    4     .probe      = i2c_device_probe,                                             
    5     .remove     = i2c_device_remove,                                            
    6     .shutdown   = i2c_device_shutdown,                                          
    7     .pm     = &i2c_device_pm_ops,                                               
    8 };                                                                              
    9 EXPORT_SYMBOL_GPL(i2c_bus_type);                    
    1 int i2c_register_driver(struct module *owner, struct i2c_driver *driver)        
    2 {                                                        
    3     ......
    4     /* add the driver to the list of i2c drivers in the driver core */          
    5     driver->driver.owner = owner;                                               
    6     driver->driver.bus = &i2c_bus_type;                                     
    7     ......
    8 }

    所以 , 驱动与设备绑定之后 , 运行的probe 是i2c_device_probe

     1 static int i2c_device_probe(struct device *dev)                                 
     2 {                                                                               
     3     struct i2c_client   *client = i2c_verify_client(dev);                       
     4     struct i2c_driver   *driver;                                                
     5     int status;                                                                 
     6                                                                                 
     7     if (!client)                                                                
     8         return 0;                                                               
     9                                                                                 
    10     driver = to_i2c_driver(dev->driver);                                        
    11     if (!driver->probe || !driver->id_table)                                    
    12         return -ENODEV;                                                         
    13     client->driver = driver;                                                    
    14     if (!device_can_wakeup(&client->dev))                                       
    15         device_init_wakeup(&client->dev,                                        
    16                     client->flags & I2C_CLIENT_WAKE);                           
    17     dev_dbg(dev, "probe
    ");                                                    
    18                                                                                 
    19     status = driver->probe(client, i2c_match_id(driver->id_table, client));     
    20     if (status) {                                                               
    21         client->driver = NULL;                                                  
    22         i2c_set_clientdata(client, NULL);                              
    23     }                                                                           
    24     return status;                                                              
    25 }                    
  • 相关阅读:
    在程序中向水晶报表传参数,以及在程序中指定报表源
    运行Web程序时提示无法使用调试
    TreeView控件节点重命名后没有进入beginEdit的解决方案
    网络负载平衡(转)
    纵横表转交叉表
    重绘datagrid,包括强迫显示某行
    datagrid添加事件
    我的页面模板算法
    C++函数重载
    关于string.empty 与 "" 内存分配
  • 原文地址:https://www.cnblogs.com/chenfulin5/p/5690661.html
Copyright © 2011-2022 走看看