/*
* 源文件目录:
* /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 */