aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDmitry Torokhov <dtor@insightbb.com>2007-04-12 01:29:46 -0400
committerDmitry Torokhov <dtor@insightbb.com>2007-04-12 01:29:46 -0400
commit5b2a08262a8c952fef008154933953f083ca5766 (patch)
tree47fb54c30509a4c444613a1737a212ddda3bb05d /drivers
parent6e782584e0713ea89da151333e7fe754c8f40324 (diff)
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/keyboard.c28
-rw-r--r--drivers/input/evbug.c32
-rw-r--r--drivers/input/evdev.c47
-rw-r--r--drivers/input/input.c88
-rw-r--r--drivers/input/joydev.c48
-rw-r--r--drivers/input/mousedev.c61
-rw-r--r--drivers/input/power.c46
-rw-r--r--drivers/input/tsdev.c58
8 files changed, 284 insertions, 124 deletions
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 3d211e8553f7..59712546f911 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -41,7 +41,6 @@
41#include <linux/input.h> 41#include <linux/input.h>
42#include <linux/reboot.h> 42#include <linux/reboot.h>
43 43
44static void kbd_disconnect(struct input_handle *handle);
45extern void ctrl_alt_del(void); 44extern void ctrl_alt_del(void);
46 45
47/* 46/*
@@ -1260,11 +1259,11 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type,
1260 * likes it, it can open it and get events from it. In this (kbd_connect) 1259 * likes it, it can open it and get events from it. In this (kbd_connect)
1261 * function, we should decide which VT to bind that keyboard to initially. 1260 * function, we should decide which VT to bind that keyboard to initially.
1262 */ 1261 */
1263static struct input_handle *kbd_connect(struct input_handler *handler, 1262static int kbd_connect(struct input_handler *handler, struct input_dev *dev,
1264 struct input_dev *dev, 1263 const struct input_device_id *id)
1265 const struct input_device_id *id)
1266{ 1264{
1267 struct input_handle *handle; 1265 struct input_handle *handle;
1266 int error;
1268 int i; 1267 int i;
1269 1268
1270 for (i = KEY_RESERVED; i < BTN_MISC; i++) 1269 for (i = KEY_RESERVED; i < BTN_MISC; i++)
@@ -1272,24 +1271,37 @@ static struct input_handle *kbd_connect(struct input_handler *handler,
1272 break; 1271 break;
1273 1272
1274 if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit)) 1273 if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit))
1275 return NULL; 1274 return -ENODEV;
1276 1275
1277 handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); 1276 handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
1278 if (!handle) 1277 if (!handle)
1279 return NULL; 1278 return -ENOMEM;
1280 1279
1281 handle->dev = dev; 1280 handle->dev = dev;
1282 handle->handler = handler; 1281 handle->handler = handler;
1283 handle->name = "kbd"; 1282 handle->name = "kbd";
1284 1283
1285 input_open_device(handle); 1284 error = input_register_handle(handle);
1285 if (error)
1286 goto err_free_handle;
1287
1288 error = input_open_device(handle);
1289 if (error)
1290 goto err_unregister_handle;
1291
1292 return 0;
1286 1293
1287 return handle; 1294 err_unregister_handle:
1295 input_unregister_handle(handle);
1296 err_free_handle:
1297 kfree(handle);
1298 return error;
1288} 1299}
1289 1300
1290static void kbd_disconnect(struct input_handle *handle) 1301static void kbd_disconnect(struct input_handle *handle)
1291{ 1302{
1292 input_close_device(handle); 1303 input_close_device(handle);
1304 input_unregister_handle(handle);
1293 kfree(handle); 1305 kfree(handle);
1294} 1306}
1295 1307
diff --git a/drivers/input/evbug.c b/drivers/input/evbug.c
index 5a9653c3128a..c21f2f127234 100644
--- a/drivers/input/evbug.c
+++ b/drivers/input/evbug.c
@@ -38,31 +38,43 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
38MODULE_DESCRIPTION("Input driver event debug module"); 38MODULE_DESCRIPTION("Input driver event debug module");
39MODULE_LICENSE("GPL"); 39MODULE_LICENSE("GPL");
40 40
41static char evbug_name[] = "evbug";
42
43static void evbug_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) 41static void evbug_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
44{ 42{
45 printk(KERN_DEBUG "evbug.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n", 43 printk(KERN_DEBUG "evbug.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n",
46 handle->dev->phys, type, code, value); 44 handle->dev->phys, type, code, value);
47} 45}
48 46
49static struct input_handle *evbug_connect(struct input_handler *handler, struct input_dev *dev, 47static int evbug_connect(struct input_handler *handler, struct input_dev *dev,
50 const struct input_device_id *id) 48 const struct input_device_id *id)
51{ 49{
52 struct input_handle *handle; 50 struct input_handle *handle;
51 int error;
53 52
54 if (!(handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL))) 53 handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
55 return NULL; 54 if (!handle)
55 return -ENOMEM;
56 56
57 handle->dev = dev; 57 handle->dev = dev;
58 handle->handler = handler; 58 handle->handler = handler;
59 handle->name = evbug_name; 59 handle->name = "evbug";
60
61 error = input_register_handle(handle);
62 if (error)
63 goto err_free_handle;
60 64
61 input_open_device(handle); 65 error = input_open_device(handle);
66 if (error)
67 goto err_unregister_handle;
62 68
63 printk(KERN_DEBUG "evbug.c: Connected device: \"%s\", %s\n", dev->name, dev->phys); 69 printk(KERN_DEBUG "evbug.c: Connected device: \"%s\", %s\n", dev->name, dev->phys);
64 70
65 return handle; 71 return 0;
72
73 err_unregister_handle:
74 input_unregister_handle(handle);
75 err_free_handle:
76 kfree(handle);
77 return error;
66} 78}
67 79
68static void evbug_disconnect(struct input_handle *handle) 80static void evbug_disconnect(struct input_handle *handle)
@@ -70,7 +82,7 @@ static void evbug_disconnect(struct input_handle *handle)
70 printk(KERN_DEBUG "evbug.c: Disconnected device: %s\n", handle->dev->phys); 82 printk(KERN_DEBUG "evbug.c: Disconnected device: %s\n", handle->dev->phys);
71 83
72 input_close_device(handle); 84 input_close_device(handle);
73 85 input_unregister_handle(handle);
74 kfree(handle); 86 kfree(handle);
75} 87}
76 88
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 64b47de052bb..840fa1986527 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -605,21 +605,24 @@ static const struct file_operations evdev_fops = {
605 .flush = evdev_flush 605 .flush = evdev_flush
606}; 606};
607 607
608static struct input_handle *evdev_connect(struct input_handler *handler, struct input_dev *dev, 608static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
609 const struct input_device_id *id) 609 const struct input_device_id *id)
610{ 610{
611 struct evdev *evdev; 611 struct evdev *evdev;
612 struct class_device *cdev; 612 struct class_device *cdev;
613 dev_t devt;
613 int minor; 614 int minor;
615 int error;
614 616
615 for (minor = 0; minor < EVDEV_MINORS && evdev_table[minor]; minor++); 617 for (minor = 0; minor < EVDEV_MINORS && evdev_table[minor]; minor++);
616 if (minor == EVDEV_MINORS) { 618 if (minor == EVDEV_MINORS) {
617 printk(KERN_ERR "evdev: no more free evdev devices\n"); 619 printk(KERN_ERR "evdev: no more free evdev devices\n");
618 return NULL; 620 return -ENFILE;
619 } 621 }
620 622
621 if (!(evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL))) 623 evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL);
622 return NULL; 624 if (!evdev)
625 return -ENOMEM;
623 626
624 INIT_LIST_HEAD(&evdev->list); 627 INIT_LIST_HEAD(&evdev->list);
625 init_waitqueue_head(&evdev->wait); 628 init_waitqueue_head(&evdev->wait);
@@ -634,15 +637,35 @@ static struct input_handle *evdev_connect(struct input_handler *handler, struct
634 637
635 evdev_table[minor] = evdev; 638 evdev_table[minor] = evdev;
636 639
637 cdev = class_device_create(&input_class, &dev->cdev, 640 devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
638 MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor), 641
639 dev->cdev.dev, evdev->name); 642 cdev = class_device_create(&input_class, &dev->cdev, devt,
643 dev->cdev.dev, evdev->name);
644 if (IS_ERR(cdev)) {
645 error = PTR_ERR(cdev);
646 goto err_free_evdev;
647 }
640 648
641 /* temporary symlink to keep userspace happy */ 649 /* temporary symlink to keep userspace happy */
642 sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj, 650 error = sysfs_create_link(&input_class.subsys.kset.kobj,
643 evdev->name); 651 &cdev->kobj, evdev->name);
652 if (error)
653 goto err_cdev_destroy;
654
655 error = input_register_handle(&evdev->handle);
656 if (error)
657 goto err_remove_link;
644 658
645 return &evdev->handle; 659 return 0;
660
661 err_remove_link:
662 sysfs_remove_link(&input_class.subsys.kset.kobj, evdev->name);
663 err_cdev_destroy:
664 class_device_destroy(&input_class, devt);
665 err_free_evdev:
666 kfree(evdev);
667 evdev_table[minor] = NULL;
668 return error;
646} 669}
647 670
648static void evdev_disconnect(struct input_handle *handle) 671static void evdev_disconnect(struct input_handle *handle)
@@ -650,6 +673,8 @@ static void evdev_disconnect(struct input_handle *handle)
650 struct evdev *evdev = handle->private; 673 struct evdev *evdev = handle->private;
651 struct evdev_list *list; 674 struct evdev_list *list;
652 675
676 input_unregister_handle(handle);
677
653 sysfs_remove_link(&input_class.subsys.kset.kobj, evdev->name); 678 sysfs_remove_link(&input_class.subsys.kset.kobj, evdev->name);
654 class_device_destroy(&input_class, 679 class_device_destroy(&input_class,
655 MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor)); 680 MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor));
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
383static 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
429static 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
437static struct proc_dir_entry *proc_bus_input_dir; 454static struct proc_dir_entry *proc_bus_input_dir;
@@ -1032,9 +1049,7 @@ EXPORT_SYMBOL(input_free_device);
1032int input_register_device(struct input_dev *dev) 1049int 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
1091void input_unregister_device(struct input_dev *dev) 1100void 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);
1118int input_register_handler(struct input_handler *handler) 1124int 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
1149void input_unregister_handler(struct input_handler *handler) 1147void 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}
1167EXPORT_SYMBOL(input_unregister_handler); 1162EXPORT_SYMBOL(input_unregister_handler);
1168 1163
1164int 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}
1176EXPORT_SYMBOL(input_register_handle);
1177
1178void input_unregister_handle(struct input_handle *handle)
1179{
1180 list_del_init(&handle->h_node);
1181 list_del_init(&handle->d_node);
1182}
1183EXPORT_SYMBOL(input_unregister_handle);
1184
1169static int input_open_file(struct inode *inode, struct file *file) 1185static 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];
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 9f3529ad3fda..cf24a5bde539 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -465,21 +465,24 @@ static const struct file_operations joydev_fops = {
465 .fasync = joydev_fasync, 465 .fasync = joydev_fasync,
466}; 466};
467 467
468static struct input_handle *joydev_connect(struct input_handler *handler, struct input_dev *dev, 468static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
469 const struct input_device_id *id) 469 const struct input_device_id *id)
470{ 470{
471 struct joydev *joydev; 471 struct joydev *joydev;
472 struct class_device *cdev; 472 struct class_device *cdev;
473 dev_t devt;
473 int i, j, t, minor; 474 int i, j, t, minor;
475 int error;
474 476
475 for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++); 477 for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++);
476 if (minor == JOYDEV_MINORS) { 478 if (minor == JOYDEV_MINORS) {
477 printk(KERN_ERR "joydev: no more free joydev devices\n"); 479 printk(KERN_ERR "joydev: no more free joydev devices\n");
478 return NULL; 480 return -ENFILE;
479 } 481 }
480 482
481 if (!(joydev = kzalloc(sizeof(struct joydev), GFP_KERNEL))) 483 joydev = kzalloc(sizeof(struct joydev), GFP_KERNEL);
482 return NULL; 484 if (!joydev)
485 return -ENOMEM;
483 486
484 INIT_LIST_HEAD(&joydev->list); 487 INIT_LIST_HEAD(&joydev->list);
485 init_waitqueue_head(&joydev->wait); 488 init_waitqueue_head(&joydev->wait);
@@ -534,22 +537,45 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct
534 537
535 joydev_table[minor] = joydev; 538 joydev_table[minor] = joydev;
536 539
537 cdev = class_device_create(&input_class, &dev->cdev, 540 devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
538 MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor), 541
539 dev->cdev.dev, joydev->name); 542 cdev = class_device_create(&input_class, &dev->cdev, devt,
543 dev->cdev.dev, joydev->name);
544 if (IS_ERR(cdev)) {
545 error = PTR_ERR(cdev);
546 goto err_free_joydev;
547 }
540 548
541 /* temporary symlink to keep userspace happy */ 549 /* temporary symlink to keep userspace happy */
542 sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj, 550 error = sysfs_create_link(&input_class.subsys.kset.kobj,
543 joydev->name); 551 &cdev->kobj, joydev->name);
552 if (error)
553 goto err_cdev_destroy;
554
555 error = input_register_handle(&joydev->handle);
556 if (error)
557 goto err_remove_link;
558
559 return 0;
544 560
545 return &joydev->handle; 561 err_remove_link:
562 sysfs_remove_link(&input_class.subsys.kset.kobj, joydev->name);
563 err_cdev_destroy:
564 class_device_destroy(&input_class, devt);
565 err_free_joydev:
566 joydev_table[minor] = NULL;
567 kfree(joydev);
568 return error;
546} 569}
547 570
571
548static void joydev_disconnect(struct input_handle *handle) 572static void joydev_disconnect(struct input_handle *handle)
549{ 573{
550 struct joydev *joydev = handle->private; 574 struct joydev *joydev = handle->private;
551 struct joydev_list *list; 575 struct joydev_list *list;
552 576
577 input_unregister_handle(handle);
578
553 sysfs_remove_link(&input_class.subsys.kset.kobj, joydev->name); 579 sysfs_remove_link(&input_class.subsys.kset.kobj, joydev->name);
554 class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor)); 580 class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor));
555 joydev->exist = 0; 581 joydev->exist = 0;
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 664bcc8116fc..007e72f80251 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -624,23 +624,27 @@ static const struct file_operations mousedev_fops = {
624 .fasync = mousedev_fasync, 624 .fasync = mousedev_fasync,
625}; 625};
626 626
627static struct input_handle *mousedev_connect(struct input_handler *handler, struct input_dev *dev, 627static int mousedev_connect(struct input_handler *handler, struct input_dev *dev,
628 const struct input_device_id *id) 628 const struct input_device_id *id)
629{ 629{
630 struct mousedev *mousedev; 630 struct mousedev *mousedev;
631 struct class_device *cdev; 631 struct class_device *cdev;
632 int minor = 0; 632 dev_t devt;
633 int minor;
634 int error;
633 635
634 for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++); 636 for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++);
635 if (minor == MOUSEDEV_MINORS) { 637 if (minor == MOUSEDEV_MINORS) {
636 printk(KERN_ERR "mousedev: no more free mousedev devices\n"); 638 printk(KERN_ERR "mousedev: no more free mousedev devices\n");
637 return NULL; 639 return -ENFILE;
638 } 640 }
639 641
640 if (!(mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL))) 642 mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL);
641 return NULL; 643 if (!mousedev)
644 return -ENOMEM;
642 645
643 INIT_LIST_HEAD(&mousedev->list); 646 INIT_LIST_HEAD(&mousedev->list);
647 INIT_LIST_HEAD(&mousedev->mixdev_node);
644 init_waitqueue_head(&mousedev->wait); 648 init_waitqueue_head(&mousedev->wait);
645 649
646 mousedev->minor = minor; 650 mousedev->minor = minor;
@@ -651,20 +655,45 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru
651 mousedev->handle.private = mousedev; 655 mousedev->handle.private = mousedev;
652 sprintf(mousedev->name, "mouse%d", minor); 656 sprintf(mousedev->name, "mouse%d", minor);
653 657
654 if (mousedev_mix.open)
655 input_open_device(&mousedev->handle);
656
657 mousedev_table[minor] = mousedev; 658 mousedev_table[minor] = mousedev;
658 659
659 cdev = class_device_create(&input_class, &dev->cdev, 660 devt = MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor),
660 MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor), 661
661 dev->cdev.dev, mousedev->name); 662 cdev = class_device_create(&input_class, &dev->cdev, devt,
663 dev->cdev.dev, mousedev->name);
664 if (IS_ERR(cdev)) {
665 error = PTR_ERR(cdev);
666 goto err_free_mousedev;
667 }
662 668
663 /* temporary symlink to keep userspace happy */ 669 /* temporary symlink to keep userspace happy */
664 sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj, 670 error = sysfs_create_link(&input_class.subsys.kset.kobj,
665 mousedev->name); 671 &cdev->kobj, mousedev->name);
672 if (error)
673 goto err_cdev_destroy;
666 674
667 return &mousedev->handle; 675 error = input_register_handle(&mousedev->handle);
676 if (error)
677 goto err_remove_link;
678
679 if (mousedev_mix.open) {
680 error = input_open_device(&mousedev->handle);
681 if (error)
682 goto err_unregister_handle;
683 }
684
685 return 0;
686
687 err_unregister_handle:
688 input_unregister_handle(&mousedev->handle);
689 err_remove_link:
690 sysfs_remove_link(&input_class.subsys.kset.kobj, mousedev->name);
691 err_cdev_destroy:
692 class_device_destroy(&input_class, devt);
693 err_free_mousedev:
694 mousedev_table[minor] = NULL;
695 kfree(mousedev);
696 return error;
668} 697}
669 698
670static void mousedev_disconnect(struct input_handle *handle) 699static void mousedev_disconnect(struct input_handle *handle)
@@ -672,6 +701,8 @@ static void mousedev_disconnect(struct input_handle *handle)
672 struct mousedev *mousedev = handle->private; 701 struct mousedev *mousedev = handle->private;
673 struct mousedev_list *list; 702 struct mousedev_list *list;
674 703
704 input_unregister_handle(handle);
705
675 sysfs_remove_link(&input_class.subsys.kset.kobj, mousedev->name); 706 sysfs_remove_link(&input_class.subsys.kset.kobj, mousedev->name);
676 class_device_destroy(&input_class, 707 class_device_destroy(&input_class,
677 MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor)); 708 MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor));
diff --git a/drivers/input/power.c b/drivers/input/power.c
index ee82464a2fa7..e28d264b9e06 100644
--- a/drivers/input/power.c
+++ b/drivers/input/power.c
@@ -41,14 +41,14 @@ static struct input_handler power_handler;
41 * Power management can't be done in a interrupt context. So we have to 41 * Power management can't be done in a interrupt context. So we have to
42 * use keventd. 42 * use keventd.
43 */ 43 */
44static int suspend_button_pushed = 0; 44static int suspend_button_pushed;
45static void suspend_button_task_handler(void *data) 45static void suspend_button_task_handler(struct work_struct *work)
46{ 46{
47 udelay(200); /* debounce */ 47 udelay(200); /* debounce */
48 suspend_button_pushed = 0; 48 suspend_button_pushed = 0;
49} 49}
50 50
51static DECLARE_WORK(suspend_button_task, suspend_button_task_handler, NULL); 51static DECLARE_WORK(suspend_button_task, suspend_button_task_handler);
52 52
53static void power_event(struct input_handle *handle, unsigned int type, 53static void power_event(struct input_handle *handle, unsigned int type,
54 unsigned int code, int down) 54 unsigned int code, int down)
@@ -63,9 +63,9 @@ static void power_event(struct input_handle *handle, unsigned int type,
63 printk("Powering down entire device\n"); 63 printk("Powering down entire device\n");
64 64
65 if (!suspend_button_pushed) { 65 if (!suspend_button_pushed) {
66 suspend_button_pushed = 1; 66 suspend_button_pushed = 1;
67 schedule_work(&suspend_button_task); 67 schedule_work(&suspend_button_task);
68 } 68 }
69 break; 69 break;
70 case KEY_POWER: 70 case KEY_POWER:
71 /* Hum power down the machine. */ 71 /* Hum power down the machine. */
@@ -84,7 +84,7 @@ static void power_event(struct input_handle *handle, unsigned int type,
84 dev->state = PM_RESUME; 84 dev->state = PM_RESUME;
85 else 85 else
86 dev->state = PM_SUSPEND; 86 dev->state = PM_SUSPEND;
87 pm_send(dev->pm_dev, dev->state, dev); 87 /* pm_send(dev->pm_dev, dev->state, dev); */
88 break; 88 break;
89 case KEY_POWER: 89 case KEY_POWER:
90 /* Turn the input device off completely ? */ 90 /* Turn the input device off completely ? */
@@ -96,27 +96,41 @@ static void power_event(struct input_handle *handle, unsigned int type,
96 return; 96 return;
97} 97}
98 98
99static struct input_handle *power_connect(struct input_handler *handler, 99static int power_connect(struct input_handler *handler, struct input_dev *dev,
100 struct input_dev *dev, 100 const struct input_device_id *id)
101 const struct input_device_id *id)
102{ 101{
103 struct input_handle *handle; 102 struct input_handle *handle;
103 int error;
104 104
105 if (!(handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL))) 105 handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
106 return NULL; 106 if (!handle)
107 return -ENOMEM;
107 108
108 handle->dev = dev; 109 handle->dev = dev;
109 handle->handler = handler; 110 handle->handler = handler;
111 handle->name = "power";
110 112
111 input_open_device(handle); 113 error = input_register_handle(handle);
114 if (error)
115 goto err_free_handle;
112 116
113 printk(KERN_INFO "power.c: Adding power management to input layer\n"); 117 error = input_open_device(handle);
114 return handle; 118 if (error)
119 goto err_unregister_handle;
120
121 return 0;
122
123 err_unregister_handle:
124 input_unregister_handle(handle);
125 err_free_handle:
126 kfree(handle);
127 return error;
115} 128}
116 129
117static void power_disconnect(struct input_handle *handle) 130static void power_disconnect(struct input_handle *handle)
118{ 131{
119 input_close_device(handle); 132 input_close_device(handle);
133 input_unregister_handle(handle);
120 kfree(handle); 134 kfree(handle);
121} 135}
122 136
@@ -135,7 +149,7 @@ static const struct input_device_id power_ids[] = {
135 .flags = INPUT_DEVICE_ID_MATCH_EVBIT, 149 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
136 .evbit = { BIT(EV_PWR) }, 150 .evbit = { BIT(EV_PWR) },
137 }, 151 },
138 { }, /* Terminating entry */ 152 { }, /* Terminating entry */
139}; 153};
140 154
141MODULE_DEVICE_TABLE(input, power_ids); 155MODULE_DEVICE_TABLE(input, power_ids);
diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c
index 0300dca8591d..a23aedc64ab1 100644
--- a/drivers/input/tsdev.c
+++ b/drivers/input/tsdev.c
@@ -155,7 +155,7 @@ static int tsdev_open(struct inode *inode, struct file *file)
155 "for removal.\nSee Documentation/feature-removal-schedule.txt " 155 "for removal.\nSee Documentation/feature-removal-schedule.txt "
156 "for details.\n"); 156 "for details.\n");
157 157
158 if (i >= TSDEV_MINORS || !tsdev_table[i & TSDEV_MINOR_MASK]) 158 if (i >= TSDEV_MINORS)
159 return -ENODEV; 159 return -ENODEV;
160 160
161 if (!(list = kzalloc(sizeof(struct tsdev_list), GFP_KERNEL))) 161 if (!(list = kzalloc(sizeof(struct tsdev_list), GFP_KERNEL)))
@@ -246,14 +246,14 @@ static int tsdev_ioctl(struct inode *inode, struct file *file,
246 246
247 switch (cmd) { 247 switch (cmd) {
248 case TS_GET_CAL: 248 case TS_GET_CAL:
249 if (copy_to_user ((void __user *)arg, &tsdev->cal, 249 if (copy_to_user((void __user *)arg, &tsdev->cal,
250 sizeof (struct ts_calibration))) 250 sizeof (struct ts_calibration)))
251 retval = -EFAULT; 251 retval = -EFAULT;
252 break; 252 break;
253 253
254 case TS_SET_CAL: 254 case TS_SET_CAL:
255 if (copy_from_user (&tsdev->cal, (void __user *)arg, 255 if (copy_from_user(&tsdev->cal, (void __user *)arg,
256 sizeof (struct ts_calibration))) 256 sizeof (struct ts_calibration)))
257 retval = -EFAULT; 257 retval = -EFAULT;
258 break; 258 break;
259 259
@@ -370,23 +370,25 @@ static void tsdev_event(struct input_handle *handle, unsigned int type,
370 wake_up_interruptible(&tsdev->wait); 370 wake_up_interruptible(&tsdev->wait);
371} 371}
372 372
373static struct input_handle *tsdev_connect(struct input_handler *handler, 373static int tsdev_connect(struct input_handler *handler, struct input_dev *dev,
374 struct input_dev *dev, 374 const struct input_device_id *id)
375 const struct input_device_id *id)
376{ 375{
377 struct tsdev *tsdev; 376 struct tsdev *tsdev;
378 struct class_device *cdev; 377 struct class_device *cdev;
378 dev_t devt;
379 int minor, delta; 379 int minor, delta;
380 int error;
380 381
381 for (minor = 0; minor < TSDEV_MINORS / 2 && tsdev_table[minor]; minor++); 382 for (minor = 0; minor < TSDEV_MINORS / 2 && tsdev_table[minor]; minor++);
382 if (minor >= TSDEV_MINORS / 2) { 383 if (minor >= TSDEV_MINORS / 2) {
383 printk(KERN_ERR 384 printk(KERN_ERR
384 "tsdev: You have way too many touchscreens\n"); 385 "tsdev: You have way too many touchscreens\n");
385 return NULL; 386 return -ENFILE;
386 } 387 }
387 388
388 if (!(tsdev = kzalloc(sizeof(struct tsdev), GFP_KERNEL))) 389 tsdev = kzalloc(sizeof(struct tsdev), GFP_KERNEL);
389 return NULL; 390 if (!tsdev)
391 return -ENOMEM;
390 392
391 INIT_LIST_HEAD(&tsdev->list); 393 INIT_LIST_HEAD(&tsdev->list);
392 init_waitqueue_head(&tsdev->wait); 394 init_waitqueue_head(&tsdev->wait);
@@ -415,15 +417,35 @@ static struct input_handle *tsdev_connect(struct input_handler *handler,
415 417
416 tsdev_table[minor] = tsdev; 418 tsdev_table[minor] = tsdev;
417 419
418 cdev = class_device_create(&input_class, &dev->cdev, 420 devt = MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor),
419 MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor), 421
420 dev->cdev.dev, tsdev->name); 422 cdev = class_device_create(&input_class, &dev->cdev, devt,
423 dev->cdev.dev, tsdev->name);
424 if (IS_ERR(cdev)) {
425 error = PTR_ERR(cdev);
426 goto err_free_tsdev;
427 }
421 428
422 /* temporary symlink to keep userspace happy */ 429 /* temporary symlink to keep userspace happy */
423 sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj, 430 error = sysfs_create_link(&input_class.subsys.kset.kobj,
424 tsdev->name); 431 &cdev->kobj, tsdev->name);
432 if (error)
433 goto err_cdev_destroy;
425 434
426 return &tsdev->handle; 435 error = input_register_handle(&tsdev->handle);
436 if (error)
437 goto err_remove_link;
438
439 return 0;
440
441 err_remove_link:
442 sysfs_remove_link(&input_class.subsys.kset.kobj, tsdev->name);
443 err_cdev_destroy:
444 class_device_destroy(&input_class, devt);
445 err_free_tsdev:
446 tsdev_table[minor] = NULL;
447 kfree(tsdev);
448 return error;
427} 449}
428 450
429static void tsdev_disconnect(struct input_handle *handle) 451static void tsdev_disconnect(struct input_handle *handle)
@@ -431,6 +453,8 @@ static void tsdev_disconnect(struct input_handle *handle)
431 struct tsdev *tsdev = handle->private; 453 struct tsdev *tsdev = handle->private;
432 struct tsdev_list *list; 454 struct tsdev_list *list;
433 455
456 input_unregister_handle(handle);
457
434 sysfs_remove_link(&input_class.subsys.kset.kobj, tsdev->name); 458 sysfs_remove_link(&input_class.subsys.kset.kobj, tsdev->name);
435 class_device_destroy(&input_class, 459 class_device_destroy(&input_class,
436 MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor)); 460 MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor));