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\n",                        
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\n",                
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!\n");                              
 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\n", 28 driver->driver.name); 29 if (driver->resume) 30 pr_warn("i2c-core: driver [%s] using legacy resume method\n", 31 driver->driver.name); 32 33 pr_debug("i2c-core: driver [%s] registered\n", 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\n", 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...\n", 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\n", 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\n",                        
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\n",                    
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\n",                  
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\n",               
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\n",               
 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\n",                    
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\n",                   
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\n",                        
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\n");                                                    
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 }                    

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值