diff options
Diffstat (limited to 'drivers/input/input.c')
-rw-r--r-- | drivers/input/input.c | 88 |
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, | |||
380 | } | 380 | } |
381 | 381 | ||
382 | 382 | ||
383 | static void input_link_handle(struct input_handle *handle) | ||
384 | { | ||
385 | list_add_tail(&handle->d_node, &handle->dev->h_list); | ||
386 | list_add_tail(&handle->h_node, &handle->handler->h_list); | ||
387 | } | ||
388 | |||
389 | #define MATCH_BIT(bit, max) \ | 383 | #define MATCH_BIT(bit, max) \ |
390 | for (i = 0; i < NBITS(max); i++) \ | 384 | for (i = 0; i < NBITS(max); i++) \ |
391 | if ((id->bit[i] & dev->bit[i]) != id->bit[i]) \ | 385 | 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 | |||
432 | return NULL; | 426 | return NULL; |
433 | } | 427 | } |
434 | 428 | ||
429 | static int input_attach_handler(struct input_dev *dev, struct input_handler *handler) | ||
430 | { | ||
431 | const struct input_device_id *id; | ||
432 | int error; | ||
433 | |||
434 | if (handler->blacklist && input_match_device(handler->blacklist, dev)) | ||
435 | return -ENODEV; | ||
436 | |||
437 | id = input_match_device(handler->id_table, dev); | ||
438 | if (!id) | ||
439 | return -ENODEV; | ||
440 | |||
441 | error = handler->connect(handler, dev, id); | ||
442 | if (error && error != -ENODEV) | ||
443 | printk(KERN_ERR | ||
444 | "input: failed to attach handler %s to device %s, " | ||
445 | "error: %d\n", | ||
446 | handler->name, kobject_name(&dev->cdev.kobj), error); | ||
447 | |||
448 | return error; | ||
449 | } | ||
450 | |||
451 | |||
435 | #ifdef CONFIG_PROC_FS | 452 | #ifdef CONFIG_PROC_FS |
436 | 453 | ||
437 | static struct proc_dir_entry *proc_bus_input_dir; | 454 | static struct proc_dir_entry *proc_bus_input_dir; |
@@ -1032,9 +1049,7 @@ EXPORT_SYMBOL(input_free_device); | |||
1032 | int input_register_device(struct input_dev *dev) | 1049 | int input_register_device(struct input_dev *dev) |
1033 | { | 1050 | { |
1034 | static atomic_t input_no = ATOMIC_INIT(0); | 1051 | static atomic_t input_no = ATOMIC_INIT(0); |
1035 | struct input_handle *handle; | ||
1036 | struct input_handler *handler; | 1052 | struct input_handler *handler; |
1037 | const struct input_device_id *id; | ||
1038 | const char *path; | 1053 | const char *path; |
1039 | int error; | 1054 | int error; |
1040 | 1055 | ||
@@ -1074,13 +1089,7 @@ int input_register_device(struct input_dev *dev) | |||
1074 | kfree(path); | 1089 | kfree(path); |
1075 | 1090 | ||
1076 | list_for_each_entry(handler, &input_handler_list, node) | 1091 | list_for_each_entry(handler, &input_handler_list, node) |
1077 | if (!handler->blacklist || !input_match_device(handler->blacklist, dev)) | 1092 | input_attach_handler(dev, handler); |
1078 | if ((id = input_match_device(handler->id_table, dev))) | ||
1079 | if ((handle = handler->connect(handler, dev, id))) { | ||
1080 | input_link_handle(handle); | ||
1081 | if (handler->start) | ||
1082 | handler->start(handle); | ||
1083 | } | ||
1084 | 1093 | ||
1085 | input_wakeup_procfs_readers(); | 1094 | input_wakeup_procfs_readers(); |
1086 | 1095 | ||
@@ -1090,7 +1099,7 @@ EXPORT_SYMBOL(input_register_device); | |||
1090 | 1099 | ||
1091 | void input_unregister_device(struct input_dev *dev) | 1100 | void input_unregister_device(struct input_dev *dev) |
1092 | { | 1101 | { |
1093 | struct list_head *node, *next; | 1102 | struct input_handle *handle, *next; |
1094 | int code; | 1103 | int code; |
1095 | 1104 | ||
1096 | for (code = 0; code <= KEY_MAX; code++) | 1105 | for (code = 0; code <= KEY_MAX; code++) |
@@ -1100,12 +1109,9 @@ void input_unregister_device(struct input_dev *dev) | |||
1100 | 1109 | ||
1101 | del_timer_sync(&dev->timer); | 1110 | del_timer_sync(&dev->timer); |
1102 | 1111 | ||
1103 | list_for_each_safe(node, next, &dev->h_list) { | 1112 | list_for_each_entry_safe(handle, next, &dev->h_list, d_node) |
1104 | struct input_handle * handle = to_handle(node); | ||
1105 | list_del_init(&handle->d_node); | ||
1106 | list_del_init(&handle->h_node); | ||
1107 | handle->handler->disconnect(handle); | 1113 | handle->handler->disconnect(handle); |
1108 | } | 1114 | WARN_ON(!list_empty(&dev->h_list)); |
1109 | 1115 | ||
1110 | list_del_init(&dev->node); | 1116 | list_del_init(&dev->node); |
1111 | 1117 | ||
@@ -1118,8 +1124,6 @@ EXPORT_SYMBOL(input_unregister_device); | |||
1118 | int input_register_handler(struct input_handler *handler) | 1124 | int input_register_handler(struct input_handler *handler) |
1119 | { | 1125 | { |
1120 | struct input_dev *dev; | 1126 | struct input_dev *dev; |
1121 | struct input_handle *handle; | ||
1122 | const struct input_device_id *id; | ||
1123 | 1127 | ||
1124 | INIT_LIST_HEAD(&handler->h_list); | 1128 | INIT_LIST_HEAD(&handler->h_list); |
1125 | 1129 | ||
@@ -1133,13 +1137,7 @@ int input_register_handler(struct input_handler *handler) | |||
1133 | list_add_tail(&handler->node, &input_handler_list); | 1137 | list_add_tail(&handler->node, &input_handler_list); |
1134 | 1138 | ||
1135 | list_for_each_entry(dev, &input_dev_list, node) | 1139 | list_for_each_entry(dev, &input_dev_list, node) |
1136 | if (!handler->blacklist || !input_match_device(handler->blacklist, dev)) | 1140 | input_attach_handler(dev, handler); |
1137 | if ((id = input_match_device(handler->id_table, dev))) | ||
1138 | if ((handle = handler->connect(handler, dev, id))) { | ||
1139 | input_link_handle(handle); | ||
1140 | if (handler->start) | ||
1141 | handler->start(handle); | ||
1142 | } | ||
1143 | 1141 | ||
1144 | input_wakeup_procfs_readers(); | 1142 | input_wakeup_procfs_readers(); |
1145 | return 0; | 1143 | return 0; |
@@ -1148,14 +1146,11 @@ EXPORT_SYMBOL(input_register_handler); | |||
1148 | 1146 | ||
1149 | void input_unregister_handler(struct input_handler *handler) | 1147 | void input_unregister_handler(struct input_handler *handler) |
1150 | { | 1148 | { |
1151 | struct list_head *node, *next; | 1149 | struct input_handle *handle, *next; |
1152 | 1150 | ||
1153 | list_for_each_safe(node, next, &handler->h_list) { | 1151 | list_for_each_entry_safe(handle, next, &handler->h_list, h_node) |
1154 | struct input_handle * handle = to_handle_h(node); | ||
1155 | list_del_init(&handle->h_node); | ||
1156 | list_del_init(&handle->d_node); | ||
1157 | handler->disconnect(handle); | 1152 | handler->disconnect(handle); |
1158 | } | 1153 | WARN_ON(!list_empty(&handler->h_list)); |
1159 | 1154 | ||
1160 | list_del_init(&handler->node); | 1155 | list_del_init(&handler->node); |
1161 | 1156 | ||
@@ -1166,6 +1161,27 @@ void input_unregister_handler(struct input_handler *handler) | |||
1166 | } | 1161 | } |
1167 | EXPORT_SYMBOL(input_unregister_handler); | 1162 | EXPORT_SYMBOL(input_unregister_handler); |
1168 | 1163 | ||
1164 | int input_register_handle(struct input_handle *handle) | ||
1165 | { | ||
1166 | struct input_handler *handler = handle->handler; | ||
1167 | |||
1168 | list_add_tail(&handle->d_node, &handle->dev->h_list); | ||
1169 | list_add_tail(&handle->h_node, &handler->h_list); | ||
1170 | |||
1171 | if (handler->start) | ||
1172 | handler->start(handle); | ||
1173 | |||
1174 | return 0; | ||
1175 | } | ||
1176 | EXPORT_SYMBOL(input_register_handle); | ||
1177 | |||
1178 | void input_unregister_handle(struct input_handle *handle) | ||
1179 | { | ||
1180 | list_del_init(&handle->h_node); | ||
1181 | list_del_init(&handle->d_node); | ||
1182 | } | ||
1183 | EXPORT_SYMBOL(input_unregister_handle); | ||
1184 | |||
1169 | static int input_open_file(struct inode *inode, struct file *file) | 1185 | static int input_open_file(struct inode *inode, struct file *file) |
1170 | { | 1186 | { |
1171 | struct input_handler *handler = input_table[iminor(inode) >> 5]; | 1187 | struct input_handler *handler = input_table[iminor(inode) >> 5]; |