/* * 源文件目录: * /drivers/input/input.c */ 入口函数: static int __init input_init(void) 1、 err = class_register(&input_class); /* class设备节点生成 */ 2、 err = input_proc_init(); /* 为添加到proc文件系统的设备节点文件做一些初始化工作 */ 3、 err = register_chrdev(INPUT_MAJOR, "input", &input_fops); /* 注册为字符型驱动 */ /* * input_fops结构体分析 */ static const struct file_operations input_fops = { .owner = THIS_MODULE, /* 模块所属者 */ .open = input_open_file, /* 打开操作函数 */ .llseek = noop_llseek, /* 绕过llseek操作 */ }; /* * input_open_file函数分析 */ static int input_open_file(struct inode *inode, struct file *file) 1. struct input_handler *handler; /* handler声明 */ /* * input_hanler结构体: * struct input_handler { void *private; void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value); bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value); bool (*match)(struct input_handler *handler, struct input_dev *dev); int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id); void (*disconnect)(struct input_handle *handle); void (*start)(struct input_handle *handle); const struct file_operations *fops; int minor; const char *name; const struct input_device_id *id_table; * struct list_head h_list; * struct list_head node; * }; */ 2. const struct file_operations *old_fops, *new_fops = NULL; /* file_operations结构体声明 */ 3. err = mutex_lock_interruptible(&input_mutex); /* 上互斥锁操作 */ 4. handler = input_table[iminor(inode) >> 5]; /* input_table链表中第iminor(inode) >> 5节点的handler */ 5. if (handler) /* 是否存在此handler */ new_fops = fops_get(handler->fops); /* 存在内容则取出此handler的fops结构体赋予new_fops */ 6. mutex_unlock(&input_mutex); /* 解除互斥锁 */ 7. old_fops = file->f_op; file->f_op = new_fops; /* 交换file_operation,使input设备可使用相应的操作函数 */ 8. err = new_fops->open(inode, file); /* 使用对于的打开函数 */ 9. fops_put(old_fops); /* 释放old_fops */ /* * input_register_device函数分析 */ int input_register_device(struct input_dev *dev); 1. static atomic_t input_no = ATOMIC_INIT(0); /* 原子变量初始化 */ 2. struct input_handler *handler; /* 新handler声明 */ 3. /* Every input device generates EV_SYN/SYN_REPORT events. */ /* 设置dev结构体 */ __set_bit(EV_SYN, dev->evbit); /* KEY_RESERVED is not supposed to be transmitted to userspace. */ __clear_bit(KEY_RESERVED, dev->keybit); /* Make sure that bitmasks not mentioned in dev->evbit are clean. */ input_cleanse_bitmasks(dev); 4. init_timer(&dev->timer); /* 初始化一个定时器 */ 5. error = device_add(&dev->dev); /* 添加设备 */ /* * device_add函数分析 */ int device_add(struct device *dev) 1. dev = get_device(dev); /* 获取dev的kobj */ struct device *get_device(struct device *dev); \--->return dev ? to_dev(kobject_get(&dev->kobj)) : NULL; 2. parent = get_device(dev->parent); /* 获取父类驱动的kobj */ setup_parent(dev, parent); /* 启动父类驱动 */ 3. error = kobject_add(&dev->kobj, dev->kobj.parent, NULL);/* 将dev->kobj, dev->kobj.parent添加至内核中 */ 6. error = mutex_lock_interruptible(&input_mutex); /* 上互斥锁 */ 7. list_add_tail(&dev->node, &input_dev_list); /* 添加到input_dev_list队列中 */ 8. list_for_each_entry(handler, &input_handler_list, node) input_attach_handler(dev, handler); /* 遍历每个节点 */ 9. input_wakeup_procfs_readers(); /* 唤醒procfs_readers */ 10. mutex_unlock(&input_mutex); /* 解除互斥锁 */ /* * input_register_handler函数分析 */ int input_register_handler(struct input_handler *handler); 1. struct input_dev *dev; /* input_dev结构体指针声明 */ 2. retval = mutex_lock_interruptible(&input_mutex); /* 上互斥锁 */ 3. INIT_LIST_HEAD(&handler->h_list); /* 初始化list的前级与后继指针都指向list */ 4. if (handler->fops != NULL) { /* 判断是否有值handler->fops */ if (input_table[handler->minor >> 5]) { /* 判断input_table[handler->minor >> 5]节点是否有值 */ retval = -EBUSY; goto out; } input_table[handler->minor >> 5] = handler; /* 将handler添加到input_table[handler->minor >> 5]节点上 */ } 5. list_add_tail(&handler->node, &input_handler_list); /* 将handler->node放入到队列中 */ 6. list_for_each_entry(dev, &input_dev_list, node) input_attach_handler(dev, handler); /* 遍历每个节点 */ 7. input_wakeup_procfs_readers(); /* 唤醒procfs_readers */ /* * input_allocate_device函数分析 */ struct input_dev *input_allocate_device(void); 1. struct input_dev *dev; /* input_dev结构体声明 */ 2. dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL); /* input_dev结构体空间分配 */ /* * 分析kzalloc函数 */ static inline void *kzalloc(size_t size, gfp_t flags) \-->return kmalloc(size, flags | __GFP_ZERO); 3. if (dev) { /* 初始化dev的成员变量 */ dev->dev.type = &input_dev_type; dev->dev.class = &input_class; device_initialize(&dev->dev); /* * device_initialize函数 */ void device_initialize(struct device *dev) { dev->kobj.kset = devices_kset; kobject_init(&dev->kobj, &device_ktype); INIT_LIST_HEAD(&dev->dma_pools); mutex_init(&dev->mutex); lockdep_set_novalidate_class(&dev->mutex); spin_lock_init(&dev->devres_lock); INIT_LIST_HEAD(&dev->devres_head); device_pm_init(dev); set_dev_node(dev, -1); } /* * 互斥锁初始化 */ mutex_init(&dev->mutex); /* * 自旋锁初始化 */ spin_lock_init(&dev->event_lock); INIT_LIST_HEAD(&dev->h_list); INIT_LIST_HEAD(&dev->node); __module_get(THIS_MODULE); } /* * input_attach_handler函数分析 */ static int input_attach_handler(struct input_dev *dev, struct input_handler *handler); 1. id = input_match_device(handler, dev); /* 比较handler与dev的id */ 2. error = handler->connect(handler, dev, id); /* 调用相应handler的connet函数 */ /* * input_register_handle函数分析 */ int input_register_handle(struct input_handle *handle) 1. error = mutex_lock_interruptible(&dev->mutex); /* 上互斥锁 */ 2. if (handler->filter) /* 使dev->h_list指向handle->d_node */ list_add_rcu(&handle->d_node, &dev->h_list); else list_add_tail_rcu(&handle->d_node, &dev->h_list); 3. mutex_unlock(&dev->mutex); /* 解除互斥锁 */1 4. list_add_tail_rcu(&handle->h_node, &handler->h_list); /* 使handler->h_list指向handle->h_node */