内核(linux-2.6.24)有一个大的框架来管理总线,外设及其驱动看外设驱动代码时,明白了这个框架,可以很方便的找到需要看的函数。
1.数据结构
这个框架涉及到3个比较重要的数据结构:
struct bus_type 用来描述总线
struct device  用来描述设备
struct device_driver 用来描述设备驱动
有如下拓扑图

内核中可以有很多的总线bus_type
总线bus_type上可以有很多的设备device
每个设备device都有它所对应的驱动device_driver
struct bus_type { //…..省略一些成员
    const char * name;
    struct kset drivers;
    struct kset devices;
    int (*match)(struct device * dev, struct device_driver * drv);
    int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
    int (*probe)(struct device * dev);
    int (*remove)(struct device * dev);
    void (*shutdown)(struct device * dev);
    int (*suspend)(struct device * dev, pm_message_t state);
    int (*suspend_late)(struct device * dev, pm_message_t state);
    int (*resume_early)(struct device * dev);
    int (*resume)(struct device * dev);
    unsigned int drivers_autoprobe:1;
};
struct device { //…..省略一些成员
    struct klist klist_children;
    struct klist_node knode_parent; /* node in sibling list */
    struct klist_node knode_driver;
    struct klist_node knode_bus;
    struct device *parent;
    char bus_id[BUS_ID_SIZE];       /* position on parent bus */
    struct bus_type * bus;          /* type of bus device is on */
    struct device_driver *driver;   /* which driver has allocated this device */
    void *driver_data;              /* data private to the driver */
    void *platform_data;            /* Platform specific data, device core doesn't touch it */
};
struct device_driver { //…..省略一些成员
    const char * name;
    struct bus_type * bus;
    int (*probe) (struct device * dev);
    int (*remove) (struct device * dev);
    void(*shutdown) (struct device * dev);
    int (*suspend) (struct device * dev, pm_message_t state);
    int (*resume) (struct device * dev);
};

按照面向对象的思想,
bus_type虚基类,子类包括 platform_bus_type,mdio_bus_type,i2c_bus_type,pci_bus_type等
device是虚基类,子类包括 platform_device, phy_device, i2c_client, pci_device等
device_driver虚基类,子类有platform_driver, phy_driver,i2c_driver, pci_driver等
2.API
框架有几个关键API:
bus_register(stuct bus_type* bus)   用来注册一条总线bus
device_register(struct device *dev)  把dev加到bus的设备列表中去
driver_register(stuct device_driver *drv)
 1. 遍历bus上所有的dev,调用 drv->match(dev,drv) 对drv与dev进行比对
 2. 比对成功后调用 dev->bus->probe(dev) 或 drv->probe(dev)
 3. 把驱动drv加入到bus的驱动列表中去
 4. 绑定drv和dev
为了便于使用,内核针对不同总线,对上述API进行了包装,衍生出了另外一批API:
platform_driver_register
platform_device_register
phy_driver_register
mdiobus_register
下面讲将这3个API
bus_register(struct bus_type *bus) 
    //没啥说的,此函数最重要一点就是 bus->drivers_autoprobe=1
driver_register(struct device_driver *drv)
    --》bus_add_driver(drv)     //若bus->drivers_autoprobe = 1         --》driver_attach(drv)         //遍历bus下所有dev,调用             --》__driver_attach(dev,drv)                 --》driver_probe_device(drv,dev)             //调用 bus_type.match(dev, drv),如果比对成功就执行                 --》really_probe(dev,drv)                     //调用 bus->probe(dev) 或 drv->probe(dev)
3.总线的注册
所有总线的注册几乎内核启动过程时完成的。
start_kernel()
 --》rest_init()
 --》kernel_init()
 --》do_basic_setup()
 --》do_initcalls()
 --》platform_bus_init()--》bus_register(&platform_bus)
 --》mdio_bus_init() --》bus_register(&mdio_bus_type)
 --》i2c_init() --》bus_register(&i2c_bus_type)
括号里的都是全局变量