aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/evdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/evdev.c')
-rw-r--r--drivers/input/evdev.c84
1 files changed, 42 insertions, 42 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index be6b93c20f60..ab4b2d9b5327 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -30,6 +30,7 @@ struct evdev {
30 wait_queue_head_t wait; 30 wait_queue_head_t wait;
31 struct evdev_client *grab; 31 struct evdev_client *grab;
32 struct list_head client_list; 32 struct list_head client_list;
33 struct device dev;
33}; 34};
34 35
35struct evdev_client { 36struct evdev_client {
@@ -94,8 +95,10 @@ static int evdev_flush(struct file *file, fl_owner_t id)
94 return input_flush_device(&evdev->handle, file); 95 return input_flush_device(&evdev->handle, file);
95} 96}
96 97
97static void evdev_free(struct evdev *evdev) 98static void evdev_free(struct device *dev)
98{ 99{
100 struct evdev *evdev = container_of(dev, struct evdev, dev);
101
99 evdev_table[evdev->minor] = NULL; 102 evdev_table[evdev->minor] = NULL;
100 kfree(evdev); 103 kfree(evdev);
101} 104}
@@ -114,12 +117,10 @@ static int evdev_release(struct inode *inode, struct file *file)
114 list_del(&client->node); 117 list_del(&client->node);
115 kfree(client); 118 kfree(client);
116 119
117 if (!--evdev->open) { 120 if (!--evdev->open && evdev->exist)
118 if (evdev->exist) 121 input_close_device(&evdev->handle);
119 input_close_device(&evdev->handle); 122
120 else 123 put_device(&evdev->dev);
121 evdev_free(evdev);
122 }
123 124
124 return 0; 125 return 0;
125} 126}
@@ -139,24 +140,32 @@ static int evdev_open(struct inode *inode, struct file *file)
139 if (!evdev || !evdev->exist) 140 if (!evdev || !evdev->exist)
140 return -ENODEV; 141 return -ENODEV;
141 142
143 get_device(&evdev->dev);
144
142 client = kzalloc(sizeof(struct evdev_client), GFP_KERNEL); 145 client = kzalloc(sizeof(struct evdev_client), GFP_KERNEL);
143 if (!client) 146 if (!client) {
144 return -ENOMEM; 147 error = -ENOMEM;
148 goto err_put_evdev;
149 }
145 150
146 client->evdev = evdev; 151 client->evdev = evdev;
147 list_add_tail(&client->node, &evdev->client_list); 152 list_add_tail(&client->node, &evdev->client_list);
148 153
149 if (!evdev->open++ && evdev->exist) { 154 if (!evdev->open++ && evdev->exist) {
150 error = input_open_device(&evdev->handle); 155 error = input_open_device(&evdev->handle);
151 if (error) { 156 if (error)
152 list_del(&client->node); 157 goto err_free_client;
153 kfree(client);
154 return error;
155 }
156 } 158 }
157 159
158 file->private_data = client; 160 file->private_data = client;
159 return 0; 161 return 0;
162
163 err_free_client:
164 list_del(&client->node);
165 kfree(client);
166 err_put_evdev:
167 put_device(&evdev->dev);
168 return error;
160} 169}
161 170
162#ifdef CONFIG_COMPAT 171#ifdef CONFIG_COMPAT
@@ -625,8 +634,6 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
625 const struct input_device_id *id) 634 const struct input_device_id *id)
626{ 635{
627 struct evdev *evdev; 636 struct evdev *evdev;
628 struct class_device *cdev;
629 dev_t devt;
630 int minor; 637 int minor;
631 int error; 638 int error;
632 639
@@ -649,38 +656,32 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
649 evdev->handle.name = evdev->name; 656 evdev->handle.name = evdev->name;
650 evdev->handle.handler = handler; 657 evdev->handle.handler = handler;
651 evdev->handle.private = evdev; 658 evdev->handle.private = evdev;
652 sprintf(evdev->name, "event%d", minor); 659 snprintf(evdev->name, sizeof(evdev->name), "event%d", minor);
653
654 evdev_table[minor] = evdev;
655 660
656 devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor), 661 snprintf(evdev->dev.bus_id, sizeof(evdev->dev.bus_id),
662 "event%d", minor);
663 evdev->dev.class = &input_class;
664 evdev->dev.parent = &dev->dev;
665 evdev->dev.devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor);
666 evdev->dev.release = evdev_free;
667 device_initialize(&evdev->dev);
657 668
658 cdev = class_device_create(&input_class, &dev->cdev, devt, 669 evdev_table[minor] = evdev;
659 dev->cdev.dev, evdev->name);
660 if (IS_ERR(cdev)) {
661 error = PTR_ERR(cdev);
662 goto err_free_evdev;
663 }
664 670
665 /* temporary symlink to keep userspace happy */ 671 error = device_add(&evdev->dev);
666 error = sysfs_create_link(&input_class.subsys.kobj,
667 &cdev->kobj, evdev->name);
668 if (error) 672 if (error)
669 goto err_cdev_destroy; 673 goto err_free_evdev;
670 674
671 error = input_register_handle(&evdev->handle); 675 error = input_register_handle(&evdev->handle);
672 if (error) 676 if (error)
673 goto err_remove_link; 677 goto err_delete_evdev;
674 678
675 return 0; 679 return 0;
676 680
677 err_remove_link: 681 err_delete_evdev:
678 sysfs_remove_link(&input_class.subsys.kobj, evdev->name); 682 device_del(&evdev->dev);
679 err_cdev_destroy:
680 class_device_destroy(&input_class, devt);
681 err_free_evdev: 683 err_free_evdev:
682 kfree(evdev); 684 put_device(&evdev->dev);
683 evdev_table[minor] = NULL;
684 return error; 685 return error;
685} 686}
686 687
@@ -690,10 +691,8 @@ static void evdev_disconnect(struct input_handle *handle)
690 struct evdev_client *client; 691 struct evdev_client *client;
691 692
692 input_unregister_handle(handle); 693 input_unregister_handle(handle);
694 device_del(&evdev->dev);
693 695
694 sysfs_remove_link(&input_class.subsys.kobj, evdev->name);
695 class_device_destroy(&input_class,
696 MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor));
697 evdev->exist = 0; 696 evdev->exist = 0;
698 697
699 if (evdev->open) { 698 if (evdev->open) {
@@ -702,8 +701,9 @@ static void evdev_disconnect(struct input_handle *handle)
702 list_for_each_entry(client, &evdev->client_list, node) 701 list_for_each_entry(client, &evdev->client_list, node)
703 kill_fasync(&client->fasync, SIGIO, POLL_HUP); 702 kill_fasync(&client->fasync, SIGIO, POLL_HUP);
704 wake_up_interruptible(&evdev->wait); 703 wake_up_interruptible(&evdev->wait);
705 } else 704 }
706 evdev_free(evdev); 705
706 put_device(&evdev->dev);
707} 707}
708 708
709static const struct input_device_id evdev_ids[] = { 709static const struct input_device_id evdev_ids[] = {