Commit 5b2a08262a8c952fef008154933953f083ca5766

Authored by Dmitry Torokhov
1 parent 6e782584e0

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>

Showing 9 changed files with 288 additions and 125 deletions Side-by-side Diff

drivers/char/keyboard.c
... ... @@ -41,7 +41,6 @@
41 41 #include <linux/input.h>
42 42 #include <linux/reboot.h>
43 43  
44   -static void kbd_disconnect(struct input_handle *handle);
45 44 extern void ctrl_alt_del(void);
46 45  
47 46 /*
48 47  
... ... @@ -1260,11 +1259,11 @@
1260 1259 * likes it, it can open it and get events from it. In this (kbd_connect)
1261 1260 * function, we should decide which VT to bind that keyboard to initially.
1262 1261 */
1263   -static struct input_handle *kbd_connect(struct input_handler *handler,
1264   - struct input_dev *dev,
1265   - const struct input_device_id *id)
  1262 +static int kbd_connect(struct input_handler *handler, struct input_dev *dev,
  1263 + const struct input_device_id *id)
1266 1264 {
1267 1265 struct input_handle *handle;
  1266 + int error;
1268 1267 int i;
1269 1268  
1270 1269 for (i = KEY_RESERVED; i < BTN_MISC; i++)
1271 1270  
1272 1271  
1273 1272  
1274 1273  
... ... @@ -1272,24 +1271,37 @@
1272 1271 break;
1273 1272  
1274 1273 if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit))
1275   - return NULL;
  1274 + return -ENODEV;
1276 1275  
1277 1276 handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
1278 1277 if (!handle)
1279   - return NULL;
  1278 + return -ENOMEM;
1280 1279  
1281 1280 handle->dev = dev;
1282 1281 handle->handler = handler;
1283 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;
1286 1287  
1287   - return handle;
  1288 + error = input_open_device(handle);
  1289 + if (error)
  1290 + goto err_unregister_handle;
  1291 +
  1292 + return 0;
  1293 +
  1294 + err_unregister_handle:
  1295 + input_unregister_handle(handle);
  1296 + err_free_handle:
  1297 + kfree(handle);
  1298 + return error;
1288 1299 }
1289 1300  
1290 1301 static void kbd_disconnect(struct input_handle *handle)
1291 1302 {
1292 1303 input_close_device(handle);
  1304 + input_unregister_handle(handle);
1293 1305 kfree(handle);
1294 1306 }
1295 1307  
drivers/input/evbug.c
... ... @@ -38,31 +38,43 @@
38 38 MODULE_DESCRIPTION("Input driver event debug module");
39 39 MODULE_LICENSE("GPL");
40 40  
41   -static char evbug_name[] = "evbug";
42   -
43 41 static void evbug_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
44 42 {
45 43 printk(KERN_DEBUG "evbug.c: Event. Dev: %s, Type: %d, Code: %d, Value: %d\n",
46 44 handle->dev->phys, type, code, value);
47 45 }
48 46  
49   -static struct input_handle *evbug_connect(struct input_handler *handler, struct input_dev *dev,
50   - const struct input_device_id *id)
  47 +static int evbug_connect(struct input_handler *handler, struct input_dev *dev,
  48 + const struct input_device_id *id)
51 49 {
52 50 struct input_handle *handle;
  51 + int error;
53 52  
54   - if (!(handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL)))
55   - return NULL;
  53 + handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
  54 + if (!handle)
  55 + return -ENOMEM;
56 56  
57 57 handle->dev = dev;
58 58 handle->handler = handler;
59   - handle->name = evbug_name;
  59 + handle->name = "evbug";
60 60  
61   - input_open_device(handle);
  61 + error = input_register_handle(handle);
  62 + if (error)
  63 + goto err_free_handle;
62 64  
  65 + error = input_open_device(handle);
  66 + if (error)
  67 + goto err_unregister_handle;
  68 +
63 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  
68 80 static void evbug_disconnect(struct input_handle *handle)
... ... @@ -70,7 +82,7 @@
70 82 printk(KERN_DEBUG "evbug.c: Disconnected device: %s\n", handle->dev->phys);
71 83  
72 84 input_close_device(handle);
73   -
  85 + input_unregister_handle(handle);
74 86 kfree(handle);
75 87 }
76 88  
drivers/input/evdev.c
... ... @@ -605,21 +605,24 @@
605 605 .flush = evdev_flush
606 606 };
607 607  
608   -static struct input_handle *evdev_connect(struct input_handler *handler, struct input_dev *dev,
609   - const struct input_device_id *id)
  608 +static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
  609 + const struct input_device_id *id)
610 610 {
611 611 struct evdev *evdev;
612 612 struct class_device *cdev;
  613 + dev_t devt;
613 614 int minor;
  615 + int error;
614 616  
615 617 for (minor = 0; minor < EVDEV_MINORS && evdev_table[minor]; minor++);
616 618 if (minor == EVDEV_MINORS) {
617 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)))
622   - return NULL;
  623 + evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL);
  624 + if (!evdev)
  625 + return -ENOMEM;
623 626  
624 627 INIT_LIST_HEAD(&evdev->list);
625 628 init_waitqueue_head(&evdev->wait);
626 629  
627 630  
628 631  
629 632  
... ... @@ -634,21 +637,43 @@
634 637  
635 638 evdev_table[minor] = evdev;
636 639  
637   - cdev = class_device_create(&input_class, &dev->cdev,
638   - MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
639   - dev->cdev.dev, evdev->name);
  640 + devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
640 641  
  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 + }
  648 +
641 649 /* temporary symlink to keep userspace happy */
642   - sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj,
643   - evdev->name);
  650 + error = sysfs_create_link(&input_class.subsys.kset.kobj,
  651 + &cdev->kobj, evdev->name);
  652 + if (error)
  653 + goto err_cdev_destroy;
644 654  
645   - return &evdev->handle;
  655 + error = input_register_handle(&evdev->handle);
  656 + if (error)
  657 + goto err_remove_link;
  658 +
  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  
648 671 static void evdev_disconnect(struct input_handle *handle)
649 672 {
650 673 struct evdev *evdev = handle->private;
651 674 struct evdev_list *list;
  675 +
  676 + input_unregister_handle(handle);
652 677  
653 678 sysfs_remove_link(&input_class.subsys.kset.kobj, evdev->name);
654 679 class_device_destroy(&input_class,
drivers/input/input.c
... ... @@ -380,12 +380,6 @@
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 383 #define MATCH_BIT(bit, max) \
390 384 for (i = 0; i < NBITS(max); i++) \
391 385 if ((id->bit[i] & dev->bit[i]) != id->bit[i]) \
... ... @@ -432,6 +426,29 @@
432 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 452 #ifdef CONFIG_PROC_FS
436 453  
437 454 static struct proc_dir_entry *proc_bus_input_dir;
438 455  
... ... @@ -1032,9 +1049,7 @@
1032 1049 int input_register_device(struct input_dev *dev)
1033 1050 {
1034 1051 static atomic_t input_no = ATOMIC_INIT(0);
1035   - struct input_handle *handle;
1036 1052 struct input_handler *handler;
1037   - const struct input_device_id *id;
1038 1053 const char *path;
1039 1054 int error;
1040 1055  
... ... @@ -1074,13 +1089,7 @@
1074 1089 kfree(path);
1075 1090  
1076 1091 list_for_each_entry(handler, &input_handler_list, node)
1077   - if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
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   - }
  1092 + input_attach_handler(dev, handler);
1084 1093  
1085 1094 input_wakeup_procfs_readers();
1086 1095  
... ... @@ -1090,7 +1099,7 @@
1090 1099  
1091 1100 void input_unregister_device(struct input_dev *dev)
1092 1101 {
1093   - struct list_head *node, *next;
  1102 + struct input_handle *handle, *next;
1094 1103 int code;
1095 1104  
1096 1105 for (code = 0; code <= KEY_MAX; code++)
1097 1106  
... ... @@ -1100,12 +1109,9 @@
1100 1109  
1101 1110 del_timer_sync(&dev->timer);
1102 1111  
1103   - list_for_each_safe(node, next, &dev->h_list) {
1104   - struct input_handle * handle = to_handle(node);
1105   - list_del_init(&handle->d_node);
1106   - list_del_init(&handle->h_node);
  1112 + list_for_each_entry_safe(handle, next, &dev->h_list, d_node)
1107 1113 handle->handler->disconnect(handle);
1108   - }
  1114 + WARN_ON(!list_empty(&dev->h_list));
1109 1115  
1110 1116 list_del_init(&dev->node);
1111 1117  
... ... @@ -1118,8 +1124,6 @@
1118 1124 int input_register_handler(struct input_handler *handler)
1119 1125 {
1120 1126 struct input_dev *dev;
1121   - struct input_handle *handle;
1122   - const struct input_device_id *id;
1123 1127  
1124 1128 INIT_LIST_HEAD(&handler->h_list);
1125 1129  
... ... @@ -1133,13 +1137,7 @@
1133 1137 list_add_tail(&handler->node, &input_handler_list);
1134 1138  
1135 1139 list_for_each_entry(dev, &input_dev_list, node)
1136   - if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
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   - }
  1140 + input_attach_handler(dev, handler);
1143 1141  
1144 1142 input_wakeup_procfs_readers();
1145 1143 return 0;
1146 1144  
1147 1145  
... ... @@ -1148,14 +1146,11 @@
1148 1146  
1149 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) {
1154   - struct input_handle * handle = to_handle_h(node);
1155   - list_del_init(&handle->h_node);
1156   - list_del_init(&handle->d_node);
  1151 + list_for_each_entry_safe(handle, next, &handler->h_list, h_node)
1157 1152 handler->disconnect(handle);
1158   - }
  1153 + WARN_ON(!list_empty(&handler->h_list));
1159 1154  
1160 1155 list_del_init(&handler->node);
1161 1156  
... ... @@ -1165,6 +1160,27 @@
1165 1160 input_wakeup_procfs_readers();
1166 1161 }
1167 1162 EXPORT_SYMBOL(input_unregister_handler);
  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);
1168 1184  
1169 1185 static int input_open_file(struct inode *inode, struct file *file)
1170 1186 {
drivers/input/joydev.c
... ... @@ -465,21 +465,24 @@
465 465 .fasync = joydev_fasync,
466 466 };
467 467  
468   -static struct input_handle *joydev_connect(struct input_handler *handler, struct input_dev *dev,
469   - const struct input_device_id *id)
  468 +static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
  469 + const struct input_device_id *id)
470 470 {
471 471 struct joydev *joydev;
472 472 struct class_device *cdev;
  473 + dev_t devt;
473 474 int i, j, t, minor;
  475 + int error;
474 476  
475 477 for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++);
476 478 if (minor == JOYDEV_MINORS) {
477 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)))
482   - return NULL;
  483 + joydev = kzalloc(sizeof(struct joydev), GFP_KERNEL);
  484 + if (!joydev)
  485 + return -ENOMEM;
483 486  
484 487 INIT_LIST_HEAD(&joydev->list);
485 488 init_waitqueue_head(&joydev->wait);
486 489  
487 490  
488 491  
489 492  
490 493  
... ... @@ -534,21 +537,44 @@
534 537  
535 538 joydev_table[minor] = joydev;
536 539  
537   - cdev = class_device_create(&input_class, &dev->cdev,
538   - MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
539   - dev->cdev.dev, joydev->name);
  540 + devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
540 541  
  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 + }
  548 +
541 549 /* temporary symlink to keep userspace happy */
542   - sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj,
543   - joydev->name);
  550 + error = sysfs_create_link(&input_class.subsys.kset.kobj,
  551 + &cdev->kobj, joydev->name);
  552 + if (error)
  553 + goto err_cdev_destroy;
544 554  
545   - return &joydev->handle;
  555 + error = input_register_handle(&joydev->handle);
  556 + if (error)
  557 + goto err_remove_link;
  558 +
  559 + return 0;
  560 +
  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 +
548 572 static void joydev_disconnect(struct input_handle *handle)
549 573 {
550 574 struct joydev *joydev = handle->private;
551 575 struct joydev_list *list;
  576 +
  577 + input_unregister_handle(handle);
552 578  
553 579 sysfs_remove_link(&input_class.subsys.kset.kobj, joydev->name);
554 580 class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor));
drivers/input/mousedev.c
... ... @@ -624,23 +624,27 @@
624 624 .fasync = mousedev_fasync,
625 625 };
626 626  
627   -static struct input_handle *mousedev_connect(struct input_handler *handler, struct input_dev *dev,
628   - const struct input_device_id *id)
  627 +static int mousedev_connect(struct input_handler *handler, struct input_dev *dev,
  628 + const struct input_device_id *id)
629 629 {
630 630 struct mousedev *mousedev;
631 631 struct class_device *cdev;
632   - int minor = 0;
  632 + dev_t devt;
  633 + int minor;
  634 + int error;
633 635  
634 636 for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++);
635 637 if (minor == MOUSEDEV_MINORS) {
636 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)))
641   - return NULL;
  642 + mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL);
  643 + if (!mousedev)
  644 + return -ENOMEM;
642 645  
643 646 INIT_LIST_HEAD(&mousedev->list);
  647 + INIT_LIST_HEAD(&mousedev->mixdev_node);
644 648 init_waitqueue_head(&mousedev->wait);
645 649  
646 650 mousedev->minor = minor;
647 651  
648 652  
649 653  
650 654  
651 655  
... ... @@ -651,26 +655,53 @@
651 655 mousedev->handle.private = mousedev;
652 656 sprintf(mousedev->name, "mouse%d", minor);
653 657  
654   - if (mousedev_mix.open)
655   - input_open_device(&mousedev->handle);
656   -
657 658 mousedev_table[minor] = mousedev;
658 659  
659   - cdev = class_device_create(&input_class, &dev->cdev,
660   - MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor),
661   - dev->cdev.dev, mousedev->name);
  660 + devt = MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor),
662 661  
  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 + }
  668 +
663 669 /* temporary symlink to keep userspace happy */
664   - sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj,
665   - mousedev->name);
  670 + error = sysfs_create_link(&input_class.subsys.kset.kobj,
  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  
670 699 static void mousedev_disconnect(struct input_handle *handle)
671 700 {
672 701 struct mousedev *mousedev = handle->private;
673 702 struct mousedev_list *list;
  703 +
  704 + input_unregister_handle(handle);
674 705  
675 706 sysfs_remove_link(&input_class.subsys.kset.kobj, mousedev->name);
676 707 class_device_destroy(&input_class,
drivers/input/power.c
... ... @@ -41,14 +41,14 @@
41 41 * Power management can't be done in a interrupt context. So we have to
42 42 * use keventd.
43 43 */
44   -static int suspend_button_pushed = 0;
45   -static void suspend_button_task_handler(void *data)
  44 +static int suspend_button_pushed;
  45 +static void suspend_button_task_handler(struct work_struct *work)
46 46 {
47 47 udelay(200); /* debounce */
48 48 suspend_button_pushed = 0;
49 49 }
50 50  
51   -static DECLARE_WORK(suspend_button_task, suspend_button_task_handler, NULL);
  51 +static DECLARE_WORK(suspend_button_task, suspend_button_task_handler);
52 52  
53 53 static void power_event(struct input_handle *handle, unsigned int type,
54 54 unsigned int code, int down)
... ... @@ -63,9 +63,9 @@
63 63 printk("Powering down entire device\n");
64 64  
65 65 if (!suspend_button_pushed) {
66   - suspend_button_pushed = 1;
67   - schedule_work(&suspend_button_task);
68   - }
  66 + suspend_button_pushed = 1;
  67 + schedule_work(&suspend_button_task);
  68 + }
69 69 break;
70 70 case KEY_POWER:
71 71 /* Hum power down the machine. */
... ... @@ -84,7 +84,7 @@
84 84 dev->state = PM_RESUME;
85 85 else
86 86 dev->state = PM_SUSPEND;
87   - pm_send(dev->pm_dev, dev->state, dev);
  87 + /* pm_send(dev->pm_dev, dev->state, dev); */
88 88 break;
89 89 case KEY_POWER:
90 90 /* Turn the input device off completely ? */
91 91  
92 92  
93 93  
94 94  
95 95  
96 96  
... ... @@ -96,27 +96,41 @@
96 96 return;
97 97 }
98 98  
99   -static struct input_handle *power_connect(struct input_handler *handler,
100   - struct input_dev *dev,
101   - const struct input_device_id *id)
  99 +static int power_connect(struct input_handler *handler, struct input_dev *dev,
  100 + const struct input_device_id *id)
102 101 {
103 102 struct input_handle *handle;
  103 + int error;
104 104  
105   - if (!(handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL)))
106   - return NULL;
  105 + handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
  106 + if (!handle)
  107 + return -ENOMEM;
107 108  
108 109 handle->dev = dev;
109 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");
114   - return handle;
  117 + error = input_open_device(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  
117 130 static void power_disconnect(struct input_handle *handle)
118 131 {
119 132 input_close_device(handle);
  133 + input_unregister_handle(handle);
120 134 kfree(handle);
121 135 }
122 136  
... ... @@ -135,7 +149,7 @@
135 149 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
136 150 .evbit = { BIT(EV_PWR) },
137 151 },
138   - { }, /* Terminating entry */
  152 + { }, /* Terminating entry */
139 153 };
140 154  
141 155 MODULE_DEVICE_TABLE(input, power_ids);
drivers/input/tsdev.c
... ... @@ -155,7 +155,7 @@
155 155 "for removal.\nSee Documentation/feature-removal-schedule.txt "
156 156 "for details.\n");
157 157  
158   - if (i >= TSDEV_MINORS || !tsdev_table[i & TSDEV_MINOR_MASK])
  158 + if (i >= TSDEV_MINORS)
159 159 return -ENODEV;
160 160  
161 161 if (!(list = kzalloc(sizeof(struct tsdev_list), GFP_KERNEL)))
162 162  
... ... @@ -246,14 +246,14 @@
246 246  
247 247 switch (cmd) {
248 248 case TS_GET_CAL:
249   - if (copy_to_user ((void __user *)arg, &tsdev->cal,
250   - sizeof (struct ts_calibration)))
  249 + if (copy_to_user((void __user *)arg, &tsdev->cal,
  250 + sizeof (struct ts_calibration)))
251 251 retval = -EFAULT;
252 252 break;
253 253  
254 254 case TS_SET_CAL:
255   - if (copy_from_user (&tsdev->cal, (void __user *)arg,
256   - sizeof (struct ts_calibration)))
  255 + if (copy_from_user(&tsdev->cal, (void __user *)arg,
  256 + sizeof (struct ts_calibration)))
257 257 retval = -EFAULT;
258 258 break;
259 259  
260 260  
261 261  
262 262  
263 263  
... ... @@ -370,23 +370,25 @@
370 370 wake_up_interruptible(&tsdev->wait);
371 371 }
372 372  
373   -static struct input_handle *tsdev_connect(struct input_handler *handler,
374   - struct input_dev *dev,
375   - const struct input_device_id *id)
  373 +static int tsdev_connect(struct input_handler *handler, struct input_dev *dev,
  374 + const struct input_device_id *id)
376 375 {
377 376 struct tsdev *tsdev;
378 377 struct class_device *cdev;
  378 + dev_t devt;
379 379 int minor, delta;
  380 + int error;
380 381  
381 382 for (minor = 0; minor < TSDEV_MINORS / 2 && tsdev_table[minor]; minor++);
382 383 if (minor >= TSDEV_MINORS / 2) {
383 384 printk(KERN_ERR
384 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   - return NULL;
  389 + tsdev = kzalloc(sizeof(struct tsdev), GFP_KERNEL);
  390 + if (!tsdev)
  391 + return -ENOMEM;
390 392  
391 393 INIT_LIST_HEAD(&tsdev->list);
392 394 init_waitqueue_head(&tsdev->wait);
393 395  
394 396  
395 397  
396 398  
... ... @@ -415,21 +417,43 @@
415 417  
416 418 tsdev_table[minor] = tsdev;
417 419  
418   - cdev = class_device_create(&input_class, &dev->cdev,
419   - MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor),
420   - dev->cdev.dev, tsdev->name);
  420 + devt = MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor),
421 421  
  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 + }
  428 +
422 429 /* temporary symlink to keep userspace happy */
423   - sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj,
424   - tsdev->name);
  430 + error = sysfs_create_link(&input_class.subsys.kset.kobj,
  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  
429 451 static void tsdev_disconnect(struct input_handle *handle)
430 452 {
431 453 struct tsdev *tsdev = handle->private;
432 454 struct tsdev_list *list;
  455 +
  456 + input_unregister_handle(handle);
433 457  
434 458 sysfs_remove_link(&input_class.subsys.kset.kobj, tsdev->name);
435 459 class_device_destroy(&input_class,
include/linux/input.h
... ... @@ -1049,7 +1049,7 @@
1049 1049 void *private;
1050 1050  
1051 1051 void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
1052   - struct input_handle* (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);
  1052 + int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);
1053 1053 void (*disconnect)(struct input_handle *handle);
1054 1054 void (*start)(struct input_handle *handle);
1055 1055  
... ... @@ -1101,6 +1101,9 @@
1101 1101  
1102 1102 int input_register_handler(struct input_handler *);
1103 1103 void input_unregister_handler(struct input_handler *);
  1104 +
  1105 +int input_register_handle(struct input_handle *);
  1106 +void input_unregister_handle(struct input_handle *);
1104 1107  
1105 1108 int input_grab_device(struct input_handle *);
1106 1109 void input_release_device(struct input_handle *);