博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux kernel 平台总线实例分析
阅读量:5153 次
发布时间:2019-06-13

本文共 70713 字,大约阅读时间需要 235 分钟。

 

 

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 * "
", where
is a short description of the type of 8 * device, like "pci" or "floppy", and
is the enumerated 9 * instance of the device, like '0' or '42'. Driver IDs are simply 10 * "
". So, extract the
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 }

 

转载于:https://www.cnblogs.com/chenfulin5/p/5690661.html

你可能感兴趣的文章