Input: rework handle creation code
- consolidate code for binding handlers to a device - return error codes from handlers connect() methods back to input core and log failures Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
This commit is contained in:
@@ -380,12 +380,6 @@ static int input_default_setkeycode(struct input_dev *dev,
|
||||
}
|
||||
|
||||
|
||||
static void input_link_handle(struct input_handle *handle)
|
||||
{
|
||||
list_add_tail(&handle->d_node, &handle->dev->h_list);
|
||||
list_add_tail(&handle->h_node, &handle->handler->h_list);
|
||||
}
|
||||
|
||||
#define MATCH_BIT(bit, max) \
|
||||
for (i = 0; i < NBITS(max); i++) \
|
||||
if ((id->bit[i] & dev->bit[i]) != id->bit[i]) \
|
||||
@@ -432,6 +426,29 @@ static const struct input_device_id *input_match_device(const struct input_devic
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int input_attach_handler(struct input_dev *dev, struct input_handler *handler)
|
||||
{
|
||||
const struct input_device_id *id;
|
||||
int error;
|
||||
|
||||
if (handler->blacklist && input_match_device(handler->blacklist, dev))
|
||||
return -ENODEV;
|
||||
|
||||
id = input_match_device(handler->id_table, dev);
|
||||
if (!id)
|
||||
return -ENODEV;
|
||||
|
||||
error = handler->connect(handler, dev, id);
|
||||
if (error && error != -ENODEV)
|
||||
printk(KERN_ERR
|
||||
"input: failed to attach handler %s to device %s, "
|
||||
"error: %d\n",
|
||||
handler->name, kobject_name(&dev->cdev.kobj), error);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
|
||||
static struct proc_dir_entry *proc_bus_input_dir;
|
||||
@@ -1032,9 +1049,7 @@ EXPORT_SYMBOL(input_free_device);
|
||||
int input_register_device(struct input_dev *dev)
|
||||
{
|
||||
static atomic_t input_no = ATOMIC_INIT(0);
|
||||
struct input_handle *handle;
|
||||
struct input_handler *handler;
|
||||
const struct input_device_id *id;
|
||||
const char *path;
|
||||
int error;
|
||||
|
||||
@@ -1074,13 +1089,7 @@ int input_register_device(struct input_dev *dev)
|
||||
kfree(path);
|
||||
|
||||
list_for_each_entry(handler, &input_handler_list, node)
|
||||
if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
|
||||
if ((id = input_match_device(handler->id_table, dev)))
|
||||
if ((handle = handler->connect(handler, dev, id))) {
|
||||
input_link_handle(handle);
|
||||
if (handler->start)
|
||||
handler->start(handle);
|
||||
}
|
||||
input_attach_handler(dev, handler);
|
||||
|
||||
input_wakeup_procfs_readers();
|
||||
|
||||
@@ -1090,7 +1099,7 @@ EXPORT_SYMBOL(input_register_device);
|
||||
|
||||
void input_unregister_device(struct input_dev *dev)
|
||||
{
|
||||
struct list_head *node, *next;
|
||||
struct input_handle *handle, *next;
|
||||
int code;
|
||||
|
||||
for (code = 0; code <= KEY_MAX; code++)
|
||||
@@ -1100,12 +1109,9 @@ void input_unregister_device(struct input_dev *dev)
|
||||
|
||||
del_timer_sync(&dev->timer);
|
||||
|
||||
list_for_each_safe(node, next, &dev->h_list) {
|
||||
struct input_handle * handle = to_handle(node);
|
||||
list_del_init(&handle->d_node);
|
||||
list_del_init(&handle->h_node);
|
||||
list_for_each_entry_safe(handle, next, &dev->h_list, d_node)
|
||||
handle->handler->disconnect(handle);
|
||||
}
|
||||
WARN_ON(!list_empty(&dev->h_list));
|
||||
|
||||
list_del_init(&dev->node);
|
||||
|
||||
@@ -1118,8 +1124,6 @@ EXPORT_SYMBOL(input_unregister_device);
|
||||
int input_register_handler(struct input_handler *handler)
|
||||
{
|
||||
struct input_dev *dev;
|
||||
struct input_handle *handle;
|
||||
const struct input_device_id *id;
|
||||
|
||||
INIT_LIST_HEAD(&handler->h_list);
|
||||
|
||||
@@ -1133,13 +1137,7 @@ int input_register_handler(struct input_handler *handler)
|
||||
list_add_tail(&handler->node, &input_handler_list);
|
||||
|
||||
list_for_each_entry(dev, &input_dev_list, node)
|
||||
if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
|
||||
if ((id = input_match_device(handler->id_table, dev)))
|
||||
if ((handle = handler->connect(handler, dev, id))) {
|
||||
input_link_handle(handle);
|
||||
if (handler->start)
|
||||
handler->start(handle);
|
||||
}
|
||||
input_attach_handler(dev, handler);
|
||||
|
||||
input_wakeup_procfs_readers();
|
||||
return 0;
|
||||
@@ -1148,14 +1146,11 @@ EXPORT_SYMBOL(input_register_handler);
|
||||
|
||||
void input_unregister_handler(struct input_handler *handler)
|
||||
{
|
||||
struct list_head *node, *next;
|
||||
struct input_handle *handle, *next;
|
||||
|
||||
list_for_each_safe(node, next, &handler->h_list) {
|
||||
struct input_handle * handle = to_handle_h(node);
|
||||
list_del_init(&handle->h_node);
|
||||
list_del_init(&handle->d_node);
|
||||
list_for_each_entry_safe(handle, next, &handler->h_list, h_node)
|
||||
handler->disconnect(handle);
|
||||
}
|
||||
WARN_ON(!list_empty(&handler->h_list));
|
||||
|
||||
list_del_init(&handler->node);
|
||||
|
||||
@@ -1166,6 +1161,27 @@ void input_unregister_handler(struct input_handler *handler)
|
||||
}
|
||||
EXPORT_SYMBOL(input_unregister_handler);
|
||||
|
||||
int input_register_handle(struct input_handle *handle)
|
||||
{
|
||||
struct input_handler *handler = handle->handler;
|
||||
|
||||
list_add_tail(&handle->d_node, &handle->dev->h_list);
|
||||
list_add_tail(&handle->h_node, &handler->h_list);
|
||||
|
||||
if (handler->start)
|
||||
handler->start(handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(input_register_handle);
|
||||
|
||||
void input_unregister_handle(struct input_handle *handle)
|
||||
{
|
||||
list_del_init(&handle->h_node);
|
||||
list_del_init(&handle->d_node);
|
||||
}
|
||||
EXPORT_SYMBOL(input_unregister_handle);
|
||||
|
||||
static int input_open_file(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct input_handler *handler = input_table[iminor(inode) >> 5];
|
||||
|
Reference in New Issue
Block a user