summaryrefslogtreecommitdiff
path: root/drivers/input/input.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/input.c')
-rw-r--r--drivers/input/input.c88
1 files changed, 52 insertions, 36 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 5629e397520d..86b27079004a 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -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];