http://blog.csdn.net/fudan_abc/article/details/1797677
总线、设备和驱动 的关系:
linux中关于设备驱动不管 usb设备,i2c设备 还是 spi设备。这些设备能够驱动起来,Linux内核中不得不了解的3个结构体。
struct bus_type{} //
struct device_driver {}
struct device{}
查看结构体定义,发现
bus_type.dev_root (类型 struct device*)
device_driver.p->driver (类型 struct device_driver *)
device.driver (类型 struct device_driver *)
总线、设备和驱动它们只见是如何和谐共处:
每次出现一个设备就要向总线汇报,或者说注册,每次出现一个驱动,也要向总线汇报,或者说注册。比如系统初始化的时候,会扫描连接了哪些设备,并为每一个设备建立起一个struct device的变量,每一次有一个驱动程序,就要准备一个struct device_driver结构的变量。把这些变量统统加入相应的链表,device 插入devices 链表,driver插入drivers链表。
device可以在计算机启动以后在插入或者拔出计算机了。因此,很难再说是先有device还是先有driver了。因为都有可能。device可以在任何时刻出现,而driver 也可以在任何时刻被加载,所以,出现的情况就是,每当一个struct device诞生,它就会去bus的drivers链表中寻找自己的另一半,反之,每当一个一个struct device_driver诞生,它就去bus的devices链表中寻找它的那些设备。如果找到了合适的,那么ok,和之前那种情况一下,调用device_bind_driver绑定好.如果找不到,没有关系,等待吧,等到昙花再开,等到风景看透,心中相信,这世界上总有一个人是你所等的,只是还没有遇到而已。
这三个结构体在 include\linux\device.h 中定义。一下将结构体定义贴出来,建议使用sourceinsight 工具查看源码。
struct bus_type {
const char*name;
const char*dev_name;
struct device*dev_root;
struct device_attribute*dev_attrs;/* use dev_groups instead */
const struct attribute_group **bus_groups;
const struct attribute_group **dev_groups;
const struct attribute_group **drv_groups;
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 (*online)(struct device *dev);
int (*offline)(struct device *dev);
int (*suspend)(struct device *dev, pm_message_t state);
int (*resume)(struct device *dev);
const struct dev_pm_ops *pm;
const struct iommu_ops *iommu_ops;
struct subsys_private *p;
struct lock_class_key lock_key;
}
struct device_driver {
const char*name;
struct bus_type*bus;
struct module*owner;
const char*mod_name;/* used for built-in modules */
bool suppress_bind_attrs;/* disables bind/unbind via sysfs */
const struct of_device_id*of_match_table;
const struct acpi_device_id*acpi_match_table;
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);
const struct attribute_group **groups;
const struct dev_pm_ops *pm;
struct driver_private *p;
}
struct device {
struct device*parent;
struct device_private*p;
struct kobject kobj;
const char*init_name; /* initial name of the device */
const struct device_type *type;
struct mutexmutex;/* mutex to synchronize calls to
* its driver.
*/
struct bus_type*bus;/* type of bus device is on */
struct device_driver *driver;/* which driver has allocated this
device */
void*platform_data;/* Platform specific data, device
core doesn't touch it */
void*driver_data;/* Driver data, set and get with
dev_set/get_drvdata */
struct dev_pm_infopower;
struct dev_pm_domain*pm_domain;
#ifdef CONFIG_PINCTRL
struct dev_pin_info*pins;
#endif
#ifdef CONFIG_NUMA
intnuma_node;/* NUMA node this device is close to */
#endif
u64*dma_mask;/* dma mask (if dma'able device) */
u64coherent_dma_mask;/* Like dma_mask, but for
alloc_coherent mappings as
not all hardware supports
64 bit addresses for consistent
allocations such descriptors. */
unsigned longdma_pfn_offset;
struct device_dma_parameters *dma_parms;
struct list_headdma_pools;/* dma pools (if dma'ble) */
struct dma_coherent_mem*dma_mem; /* internal for coherent mem
override */
#ifdef CONFIG_DMA_CMA
struct cma *cma_area;/* contiguous memory area for dma
allocations */
#endif
/* arch specific additions */
struct dev_archdataarchdata;
struct device_node*of_node; /* associated device tree node */
struct acpi_dev_nodeacpi_node; /* associated ACPI device node */
dev_tdevt;/* dev_t, creates the sysfs "dev" */
u32id;/* device instance */
spinlock_tdevres_lock;
struct list_headdevres_head;
struct klist_nodeknode_class;
struct class*class;
const struct attribute_group **groups;/* optional groups */
void(*release)(struct device *dev);
struct iommu_group*iommu_group;
booloffline_disabled:1;
booloffline:1;
}
阅读(1250) | 评论(0) | 转发(0) |