aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2012-10-08 12:07:24 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2012-10-08 12:37:55 -0400
commit7f8d4cad1e4e11a45d02bd6e024cc2812963c38a (patch)
treeac592d99a390f1aecf9944e10d05abe4ec0f1b76
parent0124be49770469cfb258d7df4693e70b4c5fb013 (diff)
Input: extend the number of event (and other) devices
Extend the amount of character devices, such as eventX, mouseX and jsX, from a hard limit of 32 per input handler to about 1024 shared across all handlers. To be compatible with legacy installations input handlers will start creating char devices with minors in their legacy range, however once legacy range is exhausted they will start allocating minors from the dynamic range 256-1024. Reviewed-by: David Herrmann <dh.herrmann@googlemail.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r--drivers/input/evdev.c99
-rw-r--r--drivers/input/input.c114
-rw-r--r--drivers/input/joydev.c88
-rw-r--r--drivers/input/mousedev.c132
-rw-r--r--include/linux/input.h10
5 files changed, 187 insertions, 256 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 118d0300f1fb..6ae2ac47c9c8 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -23,11 +23,11 @@
23#include <linux/input/mt.h> 23#include <linux/input/mt.h>
24#include <linux/major.h> 24#include <linux/major.h>
25#include <linux/device.h> 25#include <linux/device.h>
26#include <linux/cdev.h>
26#include "input-compat.h" 27#include "input-compat.h"
27 28
28struct evdev { 29struct evdev {
29 int open; 30 int open;
30 int minor;
31 struct input_handle handle; 31 struct input_handle handle;
32 wait_queue_head_t wait; 32 wait_queue_head_t wait;
33 struct evdev_client __rcu *grab; 33 struct evdev_client __rcu *grab;
@@ -35,6 +35,7 @@ struct evdev {
35 spinlock_t client_lock; /* protects client_list */ 35 spinlock_t client_lock; /* protects client_list */
36 struct mutex mutex; 36 struct mutex mutex;
37 struct device dev; 37 struct device dev;
38 struct cdev cdev;
38 bool exist; 39 bool exist;
39}; 40};
40 41
@@ -51,9 +52,6 @@ struct evdev_client {
51 struct input_event buffer[]; 52 struct input_event buffer[];
52}; 53};
53 54
54static struct evdev *evdev_table[EVDEV_MINORS];
55static DEFINE_MUTEX(evdev_table_mutex);
56
57static void __pass_event(struct evdev_client *client, 55static void __pass_event(struct evdev_client *client,
58 const struct input_event *event) 56 const struct input_event *event)
59{ 57{
@@ -310,35 +308,16 @@ static unsigned int evdev_compute_buffer_size(struct input_dev *dev)
310 308
311static int evdev_open(struct inode *inode, struct file *file) 309static int evdev_open(struct inode *inode, struct file *file)
312{ 310{
313 struct evdev *evdev; 311 struct evdev *evdev = container_of(inode->i_cdev, struct evdev, cdev);
312 unsigned int bufsize = evdev_compute_buffer_size(evdev->handle.dev);
314 struct evdev_client *client; 313 struct evdev_client *client;
315 int i = iminor(inode) - EVDEV_MINOR_BASE;
316 unsigned int bufsize;
317 int error; 314 int error;
318 315
319 if (i >= EVDEV_MINORS)
320 return -ENODEV;
321
322 error = mutex_lock_interruptible(&evdev_table_mutex);
323 if (error)
324 return error;
325 evdev = evdev_table[i];
326 if (evdev)
327 get_device(&evdev->dev);
328 mutex_unlock(&evdev_table_mutex);
329
330 if (!evdev)
331 return -ENODEV;
332
333 bufsize = evdev_compute_buffer_size(evdev->handle.dev);
334
335 client = kzalloc(sizeof(struct evdev_client) + 316 client = kzalloc(sizeof(struct evdev_client) +
336 bufsize * sizeof(struct input_event), 317 bufsize * sizeof(struct input_event),
337 GFP_KERNEL); 318 GFP_KERNEL);
338 if (!client) { 319 if (!client)
339 error = -ENOMEM; 320 return -ENOMEM;
340 goto err_put_evdev;
341 }
342 321
343 client->bufsize = bufsize; 322 client->bufsize = bufsize;
344 spin_lock_init(&client->buffer_lock); 323 spin_lock_init(&client->buffer_lock);
@@ -352,13 +331,12 @@ static int evdev_open(struct inode *inode, struct file *file)
352 file->private_data = client; 331 file->private_data = client;
353 nonseekable_open(inode, file); 332 nonseekable_open(inode, file);
354 333
334 get_device(&evdev->dev);
355 return 0; 335 return 0;
356 336
357 err_free_client: 337 err_free_client:
358 evdev_detach_client(evdev, client); 338 evdev_detach_client(evdev, client);
359 kfree(client); 339 kfree(client);
360 err_put_evdev:
361 put_device(&evdev->dev);
362 return error; 340 return error;
363} 341}
364 342
@@ -942,26 +920,6 @@ static const struct file_operations evdev_fops = {
942 .llseek = no_llseek, 920 .llseek = no_llseek,
943}; 921};
944 922
945static int evdev_install_chrdev(struct evdev *evdev)
946{
947 /*
948 * No need to do any locking here as calls to connect and
949 * disconnect are serialized by the input core
950 */
951 evdev_table[evdev->minor] = evdev;
952 return 0;
953}
954
955static void evdev_remove_chrdev(struct evdev *evdev)
956{
957 /*
958 * Lock evdev table to prevent race with evdev_open()
959 */
960 mutex_lock(&evdev_table_mutex);
961 evdev_table[evdev->minor] = NULL;
962 mutex_unlock(&evdev_table_mutex);
963}
964
965/* 923/*
966 * Mark device non-existent. This disables writes, ioctls and 924 * Mark device non-existent. This disables writes, ioctls and
967 * prevents new users from opening the device. Already posted 925 * prevents new users from opening the device. Already posted
@@ -980,7 +938,8 @@ static void evdev_cleanup(struct evdev *evdev)
980 938
981 evdev_mark_dead(evdev); 939 evdev_mark_dead(evdev);
982 evdev_hangup(evdev); 940 evdev_hangup(evdev);
983 evdev_remove_chrdev(evdev); 941
942 cdev_del(&evdev->cdev);
984 943
985 /* evdev is marked dead so no one else accesses evdev->open */ 944 /* evdev is marked dead so no one else accesses evdev->open */
986 if (evdev->open) { 945 if (evdev->open) {
@@ -991,43 +950,47 @@ static void evdev_cleanup(struct evdev *evdev)
991 950
992/* 951/*
993 * Create new evdev device. Note that input core serializes calls 952 * Create new evdev device. Note that input core serializes calls
994 * to connect and disconnect so we don't need to lock evdev_table here. 953 * to connect and disconnect.
995 */ 954 */
996static int evdev_connect(struct input_handler *handler, struct input_dev *dev, 955static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
997 const struct input_device_id *id) 956 const struct input_device_id *id)
998{ 957{
999 struct evdev *evdev; 958 struct evdev *evdev;
1000 int minor; 959 int minor;
960 int dev_no;
1001 int error; 961 int error;
1002 962
1003 for (minor = 0; minor < EVDEV_MINORS; minor++) 963 minor = input_get_new_minor(EVDEV_MINOR_BASE, EVDEV_MINORS, true);
1004 if (!evdev_table[minor]) 964 if (minor < 0) {
1005 break; 965 error = minor;
1006 966 pr_err("failed to reserve new minor: %d\n", error);
1007 if (minor == EVDEV_MINORS) { 967 return error;
1008 pr_err("no more free evdev devices\n");
1009 return -ENFILE;
1010 } 968 }
1011 969
1012 evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL); 970 evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL);
1013 if (!evdev) 971 if (!evdev) {
1014 return -ENOMEM; 972 error = -ENOMEM;
973 goto err_free_minor;
974 }
1015 975
1016 INIT_LIST_HEAD(&evdev->client_list); 976 INIT_LIST_HEAD(&evdev->client_list);
1017 spin_lock_init(&evdev->client_lock); 977 spin_lock_init(&evdev->client_lock);
1018 mutex_init(&evdev->mutex); 978 mutex_init(&evdev->mutex);
1019 init_waitqueue_head(&evdev->wait); 979 init_waitqueue_head(&evdev->wait);
1020
1021 dev_set_name(&evdev->dev, "event%d", minor);
1022 evdev->exist = true; 980 evdev->exist = true;
1023 evdev->minor = minor; 981
982 dev_no = minor;
983 /* Normalize device number if it falls into legacy range */
984 if (dev_no < EVDEV_MINOR_BASE + EVDEV_MINORS)
985 dev_no -= EVDEV_MINOR_BASE;
986 dev_set_name(&evdev->dev, "event%d", dev_no);
1024 987
1025 evdev->handle.dev = input_get_device(dev); 988 evdev->handle.dev = input_get_device(dev);
1026 evdev->handle.name = dev_name(&evdev->dev); 989 evdev->handle.name = dev_name(&evdev->dev);
1027 evdev->handle.handler = handler; 990 evdev->handle.handler = handler;
1028 evdev->handle.private = evdev; 991 evdev->handle.private = evdev;
1029 992
1030 evdev->dev.devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor); 993 evdev->dev.devt = MKDEV(INPUT_MAJOR, minor);
1031 evdev->dev.class = &input_class; 994 evdev->dev.class = &input_class;
1032 evdev->dev.parent = &dev->dev; 995 evdev->dev.parent = &dev->dev;
1033 evdev->dev.release = evdev_free; 996 evdev->dev.release = evdev_free;
@@ -1037,7 +1000,8 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
1037 if (error) 1000 if (error)
1038 goto err_free_evdev; 1001 goto err_free_evdev;
1039 1002
1040 error = evdev_install_chrdev(evdev); 1003 cdev_init(&evdev->cdev, &evdev_fops);
1004 error = cdev_add(&evdev->cdev, evdev->dev.devt, 1);
1041 if (error) 1005 if (error)
1042 goto err_unregister_handle; 1006 goto err_unregister_handle;
1043 1007
@@ -1053,6 +1017,8 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
1053 input_unregister_handle(&evdev->handle); 1017 input_unregister_handle(&evdev->handle);
1054 err_free_evdev: 1018 err_free_evdev:
1055 put_device(&evdev->dev); 1019 put_device(&evdev->dev);
1020 err_free_minor:
1021 input_free_minor(minor);
1056 return error; 1022 return error;
1057} 1023}
1058 1024
@@ -1062,6 +1028,7 @@ static void evdev_disconnect(struct input_handle *handle)
1062 1028
1063 device_del(&evdev->dev); 1029 device_del(&evdev->dev);
1064 evdev_cleanup(evdev); 1030 evdev_cleanup(evdev);
1031 input_free_minor(MINOR(evdev->dev.devt));
1065 input_unregister_handle(handle); 1032 input_unregister_handle(handle);
1066 put_device(&evdev->dev); 1033 put_device(&evdev->dev);
1067} 1034}
@@ -1078,7 +1045,7 @@ static struct input_handler evdev_handler = {
1078 .events = evdev_events, 1045 .events = evdev_events,
1079 .connect = evdev_connect, 1046 .connect = evdev_connect,
1080 .disconnect = evdev_disconnect, 1047 .disconnect = evdev_disconnect,
1081 .fops = &evdev_fops, 1048 .legacy_minors = true,
1082 .minor = EVDEV_MINOR_BASE, 1049 .minor = EVDEV_MINOR_BASE,
1083 .name = "evdev", 1050 .name = "evdev",
1084 .id_table = evdev_ids, 1051 .id_table = evdev_ids,
diff --git a/drivers/input/input.c b/drivers/input/input.c
index ace3f7c4226d..53a0ddee7872 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -14,6 +14,7 @@
14 14
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/idr.h>
17#include <linux/input/mt.h> 18#include <linux/input/mt.h>
18#include <linux/module.h> 19#include <linux/module.h>
19#include <linux/slab.h> 20#include <linux/slab.h>
@@ -32,7 +33,9 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
32MODULE_DESCRIPTION("Input core"); 33MODULE_DESCRIPTION("Input core");
33MODULE_LICENSE("GPL"); 34MODULE_LICENSE("GPL");
34 35
35#define INPUT_DEVICES 256 36#define INPUT_MAX_CHAR_DEVICES 1024
37#define INPUT_FIRST_DYNAMIC_DEV 256
38static DEFINE_IDA(input_ida);
36 39
37static LIST_HEAD(input_dev_list); 40static LIST_HEAD(input_dev_list);
38static LIST_HEAD(input_handler_list); 41static LIST_HEAD(input_handler_list);
@@ -45,8 +48,6 @@ static LIST_HEAD(input_handler_list);
45 */ 48 */
46static DEFINE_MUTEX(input_mutex); 49static DEFINE_MUTEX(input_mutex);
47 50
48static struct input_handler *input_table[8];
49
50static const struct input_value input_value_sync = { EV_SYN, SYN_REPORT, 1 }; 51static const struct input_value input_value_sync = { EV_SYN, SYN_REPORT, 1 };
51 52
52static inline int is_event_supported(unsigned int code, 53static inline int is_event_supported(unsigned int code,
@@ -1218,7 +1219,7 @@ static int input_handlers_seq_show(struct seq_file *seq, void *v)
1218 seq_printf(seq, "N: Number=%u Name=%s", state->pos, handler->name); 1219 seq_printf(seq, "N: Number=%u Name=%s", state->pos, handler->name);
1219 if (handler->filter) 1220 if (handler->filter)
1220 seq_puts(seq, " (filter)"); 1221 seq_puts(seq, " (filter)");
1221 if (handler->fops) 1222 if (handler->legacy_minors)
1222 seq_printf(seq, " Minor=%d", handler->minor); 1223 seq_printf(seq, " Minor=%d", handler->minor);
1223 seq_putc(seq, '\n'); 1224 seq_putc(seq, '\n');
1224 1225
@@ -2016,22 +2017,14 @@ EXPORT_SYMBOL(input_unregister_device);
2016int input_register_handler(struct input_handler *handler) 2017int input_register_handler(struct input_handler *handler)
2017{ 2018{
2018 struct input_dev *dev; 2019 struct input_dev *dev;
2019 int retval; 2020 int error;
2020 2021
2021 retval = mutex_lock_interruptible(&input_mutex); 2022 error = mutex_lock_interruptible(&input_mutex);
2022 if (retval) 2023 if (error)
2023 return retval; 2024 return error;
2024 2025
2025 INIT_LIST_HEAD(&handler->h_list); 2026 INIT_LIST_HEAD(&handler->h_list);
2026 2027
2027 if (handler->fops != NULL) {
2028 if (input_table[handler->minor >> 5]) {
2029 retval = -EBUSY;
2030 goto out;
2031 }
2032 input_table[handler->minor >> 5] = handler;
2033 }
2034
2035 list_add_tail(&handler->node, &input_handler_list); 2028 list_add_tail(&handler->node, &input_handler_list);
2036 2029
2037 list_for_each_entry(dev, &input_dev_list, node) 2030 list_for_each_entry(dev, &input_dev_list, node)
@@ -2039,9 +2032,8 @@ int input_register_handler(struct input_handler *handler)
2039 2032
2040 input_wakeup_procfs_readers(); 2033 input_wakeup_procfs_readers();
2041 2034
2042 out:
2043 mutex_unlock(&input_mutex); 2035 mutex_unlock(&input_mutex);
2044 return retval; 2036 return 0;
2045} 2037}
2046EXPORT_SYMBOL(input_register_handler); 2038EXPORT_SYMBOL(input_register_handler);
2047 2039
@@ -2064,9 +2056,6 @@ void input_unregister_handler(struct input_handler *handler)
2064 2056
2065 list_del_init(&handler->node); 2057 list_del_init(&handler->node);
2066 2058
2067 if (handler->fops != NULL)
2068 input_table[handler->minor >> 5] = NULL;
2069
2070 input_wakeup_procfs_readers(); 2059 input_wakeup_procfs_readers();
2071 2060
2072 mutex_unlock(&input_mutex); 2061 mutex_unlock(&input_mutex);
@@ -2183,51 +2172,52 @@ void input_unregister_handle(struct input_handle *handle)
2183} 2172}
2184EXPORT_SYMBOL(input_unregister_handle); 2173EXPORT_SYMBOL(input_unregister_handle);
2185 2174
2186static int input_open_file(struct inode *inode, struct file *file) 2175/**
2176 * input_get_new_minor - allocates a new input minor number
2177 * @legacy_base: beginning or the legacy range to be searched
2178 * @legacy_num: size of legacy range
2179 * @allow_dynamic: whether we can also take ID from the dynamic range
2180 *
2181 * This function allocates a new device minor for from input major namespace.
2182 * Caller can request legacy minor by specifying @legacy_base and @legacy_num
2183 * parameters and whether ID can be allocated from dynamic range if there are
2184 * no free IDs in legacy range.
2185 */
2186int input_get_new_minor(int legacy_base, unsigned int legacy_num,
2187 bool allow_dynamic)
2187{ 2188{
2188 struct input_handler *handler;
2189 const struct file_operations *old_fops, *new_fops = NULL;
2190 int err;
2191
2192 err = mutex_lock_interruptible(&input_mutex);
2193 if (err)
2194 return err;
2195
2196 /* No load-on-demand here? */
2197 handler = input_table[iminor(inode) >> 5];
2198 if (handler)
2199 new_fops = fops_get(handler->fops);
2200
2201 mutex_unlock(&input_mutex);
2202
2203 /* 2189 /*
2204 * That's _really_ odd. Usually NULL ->open means "nothing special", 2190 * This function should be called from input handler's ->connect()
2205 * not "no device". Oh, well... 2191 * methods, which are serialized with input_mutex, so no additional
2192 * locking is needed here.
2206 */ 2193 */
2207 if (!new_fops || !new_fops->open) { 2194 if (legacy_base >= 0) {
2208 fops_put(new_fops); 2195 int minor = ida_simple_get(&input_ida,
2209 err = -ENODEV; 2196 legacy_base,
2210 goto out; 2197 legacy_base + legacy_num,
2198 GFP_KERNEL);
2199 if (minor >= 0 || !allow_dynamic)
2200 return minor;
2211 } 2201 }
2212 2202
2213 old_fops = file->f_op; 2203 return ida_simple_get(&input_ida,
2214 file->f_op = new_fops; 2204 INPUT_FIRST_DYNAMIC_DEV, INPUT_MAX_CHAR_DEVICES,
2215 2205 GFP_KERNEL);
2216 err = new_fops->open(inode, file);
2217 if (err) {
2218 fops_put(file->f_op);
2219 file->f_op = fops_get(old_fops);
2220 }
2221 fops_put(old_fops);
2222out:
2223 return err;
2224} 2206}
2207EXPORT_SYMBOL(input_get_new_minor);
2225 2208
2226static const struct file_operations input_fops = { 2209/**
2227 .owner = THIS_MODULE, 2210 * input_free_minor - release previously allocated minor
2228 .open = input_open_file, 2211 * @minor: minor to be released
2229 .llseek = noop_llseek, 2212 *
2230}; 2213 * This function releases previously allocated input minor so that it can be
2214 * reused later.
2215 */
2216void input_free_minor(unsigned int minor)
2217{
2218 ida_simple_remove(&input_ida, minor);
2219}
2220EXPORT_SYMBOL(input_free_minor);
2231 2221
2232static int __init input_init(void) 2222static int __init input_init(void)
2233{ 2223{
@@ -2243,7 +2233,8 @@ static int __init input_init(void)
2243 if (err) 2233 if (err)
2244 goto fail1; 2234 goto fail1;
2245 2235
2246 err = register_chrdev(INPUT_MAJOR, "input", &input_fops); 2236 err = register_chrdev_region(MKDEV(INPUT_MAJOR, 0),
2237 INPUT_MAX_CHAR_DEVICES, "input");
2247 if (err) { 2238 if (err) {
2248 pr_err("unable to register char major %d", INPUT_MAJOR); 2239 pr_err("unable to register char major %d", INPUT_MAJOR);
2249 goto fail2; 2240 goto fail2;
@@ -2259,7 +2250,8 @@ static int __init input_init(void)
2259static void __exit input_exit(void) 2250static void __exit input_exit(void)
2260{ 2251{
2261 input_proc_exit(); 2252 input_proc_exit();
2262 unregister_chrdev(INPUT_MAJOR, "input"); 2253 unregister_chrdev_region(MKDEV(INPUT_MAJOR, 0),
2254 INPUT_MAX_CHAR_DEVICES);
2263 class_unregister(&input_class); 2255 class_unregister(&input_class);
2264} 2256}
2265 2257
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 78f323ea1e4b..b62b5891f399 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -27,6 +27,7 @@
27#include <linux/poll.h> 27#include <linux/poll.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/device.h> 29#include <linux/device.h>
30#include <linux/cdev.h>
30 31
31MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); 32MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
32MODULE_DESCRIPTION("Joystick device interfaces"); 33MODULE_DESCRIPTION("Joystick device interfaces");
@@ -39,13 +40,13 @@ MODULE_LICENSE("GPL");
39 40
40struct joydev { 41struct joydev {
41 int open; 42 int open;
42 int minor;
43 struct input_handle handle; 43 struct input_handle handle;
44 wait_queue_head_t wait; 44 wait_queue_head_t wait;
45 struct list_head client_list; 45 struct list_head client_list;
46 spinlock_t client_lock; /* protects client_list */ 46 spinlock_t client_lock; /* protects client_list */
47 struct mutex mutex; 47 struct mutex mutex;
48 struct device dev; 48 struct device dev;
49 struct cdev cdev;
49 bool exist; 50 bool exist;
50 51
51 struct js_corr corr[ABS_CNT]; 52 struct js_corr corr[ABS_CNT];
@@ -70,9 +71,6 @@ struct joydev_client {
70 struct list_head node; 71 struct list_head node;
71}; 72};
72 73
73static struct joydev *joydev_table[JOYDEV_MINORS];
74static DEFINE_MUTEX(joydev_table_mutex);
75
76static int joydev_correct(int value, struct js_corr *corr) 74static int joydev_correct(int value, struct js_corr *corr)
77{ 75{
78 switch (corr->type) { 76 switch (corr->type) {
@@ -252,30 +250,14 @@ static int joydev_release(struct inode *inode, struct file *file)
252 250
253static int joydev_open(struct inode *inode, struct file *file) 251static int joydev_open(struct inode *inode, struct file *file)
254{ 252{
253 struct joydev *joydev =
254 container_of(inode->i_cdev, struct joydev, cdev);
255 struct joydev_client *client; 255 struct joydev_client *client;
256 struct joydev *joydev;
257 int i = iminor(inode) - JOYDEV_MINOR_BASE;
258 int error; 256 int error;
259 257
260 if (i >= JOYDEV_MINORS)
261 return -ENODEV;
262
263 error = mutex_lock_interruptible(&joydev_table_mutex);
264 if (error)
265 return error;
266 joydev = joydev_table[i];
267 if (joydev)
268 get_device(&joydev->dev);
269 mutex_unlock(&joydev_table_mutex);
270
271 if (!joydev)
272 return -ENODEV;
273
274 client = kzalloc(sizeof(struct joydev_client), GFP_KERNEL); 258 client = kzalloc(sizeof(struct joydev_client), GFP_KERNEL);
275 if (!client) { 259 if (!client)
276 error = -ENOMEM; 260 return -ENOMEM;
277 goto err_put_joydev;
278 }
279 261
280 spin_lock_init(&client->buffer_lock); 262 spin_lock_init(&client->buffer_lock);
281 client->joydev = joydev; 263 client->joydev = joydev;
@@ -288,13 +270,12 @@ static int joydev_open(struct inode *inode, struct file *file)
288 file->private_data = client; 270 file->private_data = client;
289 nonseekable_open(inode, file); 271 nonseekable_open(inode, file);
290 272
273 get_device(&joydev->dev);
291 return 0; 274 return 0;
292 275
293 err_free_client: 276 err_free_client:
294 joydev_detach_client(joydev, client); 277 joydev_detach_client(joydev, client);
295 kfree(client); 278 kfree(client);
296 err_put_joydev:
297 put_device(&joydev->dev);
298 return error; 279 return error;
299} 280}
300 281
@@ -742,19 +723,6 @@ static const struct file_operations joydev_fops = {
742 .llseek = no_llseek, 723 .llseek = no_llseek,
743}; 724};
744 725
745static int joydev_install_chrdev(struct joydev *joydev)
746{
747 joydev_table[joydev->minor] = joydev;
748 return 0;
749}
750
751static void joydev_remove_chrdev(struct joydev *joydev)
752{
753 mutex_lock(&joydev_table_mutex);
754 joydev_table[joydev->minor] = NULL;
755 mutex_unlock(&joydev_table_mutex);
756}
757
758/* 726/*
759 * Mark device non-existent. This disables writes, ioctls and 727 * Mark device non-existent. This disables writes, ioctls and
760 * prevents new users from opening the device. Already posted 728 * prevents new users from opening the device. Already posted
@@ -773,7 +741,8 @@ static void joydev_cleanup(struct joydev *joydev)
773 741
774 joydev_mark_dead(joydev); 742 joydev_mark_dead(joydev);
775 joydev_hangup(joydev); 743 joydev_hangup(joydev);
776 joydev_remove_chrdev(joydev); 744
745 cdev_del(&joydev->cdev);
777 746
778 /* joydev is marked dead so no one else accesses joydev->open */ 747 /* joydev is marked dead so no one else accesses joydev->open */
779 if (joydev->open) 748 if (joydev->open)
@@ -798,30 +767,33 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
798 const struct input_device_id *id) 767 const struct input_device_id *id)
799{ 768{
800 struct joydev *joydev; 769 struct joydev *joydev;
801 int i, j, t, minor; 770 int i, j, t, minor, dev_no;
802 int error; 771 int error;
803 772
804 for (minor = 0; minor < JOYDEV_MINORS; minor++) 773 minor = input_get_new_minor(JOYDEV_MINOR_BASE, JOYDEV_MINORS, true);
805 if (!joydev_table[minor]) 774 if (minor < 0) {
806 break; 775 error = minor;
807 776 pr_err("failed to reserve new minor: %d\n", error);
808 if (minor == JOYDEV_MINORS) { 777 return error;
809 pr_err("no more free joydev devices\n");
810 return -ENFILE;
811 } 778 }
812 779
813 joydev = kzalloc(sizeof(struct joydev), GFP_KERNEL); 780 joydev = kzalloc(sizeof(struct joydev), GFP_KERNEL);
814 if (!joydev) 781 if (!joydev) {
815 return -ENOMEM; 782 error = -ENOMEM;
783 goto err_free_minor;
784 }
816 785
817 INIT_LIST_HEAD(&joydev->client_list); 786 INIT_LIST_HEAD(&joydev->client_list);
818 spin_lock_init(&joydev->client_lock); 787 spin_lock_init(&joydev->client_lock);
819 mutex_init(&joydev->mutex); 788 mutex_init(&joydev->mutex);
820 init_waitqueue_head(&joydev->wait); 789 init_waitqueue_head(&joydev->wait);
821
822 dev_set_name(&joydev->dev, "js%d", minor);
823 joydev->exist = true; 790 joydev->exist = true;
824 joydev->minor = minor; 791
792 dev_no = minor;
793 /* Normalize device number if it falls into legacy range */
794 if (dev_no < JOYDEV_MINOR_BASE + JOYDEV_MINORS)
795 dev_no -= JOYDEV_MINOR_BASE;
796 dev_set_name(&joydev->dev, "js%d", dev_no);
825 797
826 joydev->handle.dev = input_get_device(dev); 798 joydev->handle.dev = input_get_device(dev);
827 joydev->handle.name = dev_name(&joydev->dev); 799 joydev->handle.name = dev_name(&joydev->dev);
@@ -875,7 +847,7 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
875 } 847 }
876 } 848 }
877 849
878 joydev->dev.devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor); 850 joydev->dev.devt = MKDEV(INPUT_MAJOR, minor);
879 joydev->dev.class = &input_class; 851 joydev->dev.class = &input_class;
880 joydev->dev.parent = &dev->dev; 852 joydev->dev.parent = &dev->dev;
881 joydev->dev.release = joydev_free; 853 joydev->dev.release = joydev_free;
@@ -885,7 +857,8 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
885 if (error) 857 if (error)
886 goto err_free_joydev; 858 goto err_free_joydev;
887 859
888 error = joydev_install_chrdev(joydev); 860 cdev_init(&joydev->cdev, &joydev_fops);
861 error = cdev_add(&joydev->cdev, joydev->dev.devt, 1);
889 if (error) 862 if (error)
890 goto err_unregister_handle; 863 goto err_unregister_handle;
891 864
@@ -901,6 +874,8 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
901 input_unregister_handle(&joydev->handle); 874 input_unregister_handle(&joydev->handle);
902 err_free_joydev: 875 err_free_joydev:
903 put_device(&joydev->dev); 876 put_device(&joydev->dev);
877 err_free_minor:
878 input_free_minor(minor);
904 return error; 879 return error;
905} 880}
906 881
@@ -910,6 +885,7 @@ static void joydev_disconnect(struct input_handle *handle)
910 885
911 device_del(&joydev->dev); 886 device_del(&joydev->dev);
912 joydev_cleanup(joydev); 887 joydev_cleanup(joydev);
888 input_free_minor(MINOR(joydev->dev.devt));
913 input_unregister_handle(handle); 889 input_unregister_handle(handle);
914 put_device(&joydev->dev); 890 put_device(&joydev->dev);
915} 891}
@@ -961,7 +937,7 @@ static struct input_handler joydev_handler = {
961 .match = joydev_match, 937 .match = joydev_match,
962 .connect = joydev_connect, 938 .connect = joydev_connect,
963 .disconnect = joydev_disconnect, 939 .disconnect = joydev_disconnect,
964 .fops = &joydev_fops, 940 .legacy_minors = true,
965 .minor = JOYDEV_MINOR_BASE, 941 .minor = JOYDEV_MINOR_BASE,
966 .name = "joydev", 942 .name = "joydev",
967 .id_table = joydev_ids, 943 .id_table = joydev_ids,
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 88b962aeef13..a1b4c37956b2 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -24,6 +24,7 @@
24#include <linux/random.h> 24#include <linux/random.h>
25#include <linux/major.h> 25#include <linux/major.h>
26#include <linux/device.h> 26#include <linux/device.h>
27#include <linux/cdev.h>
27#include <linux/kernel.h> 28#include <linux/kernel.h>
28 29
29MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); 30MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
@@ -58,14 +59,15 @@ struct mousedev_hw_data {
58 59
59struct mousedev { 60struct mousedev {
60 int open; 61 int open;
61 int minor;
62 struct input_handle handle; 62 struct input_handle handle;
63 wait_queue_head_t wait; 63 wait_queue_head_t wait;
64 struct list_head client_list; 64 struct list_head client_list;
65 spinlock_t client_lock; /* protects client_list */ 65 spinlock_t client_lock; /* protects client_list */
66 struct mutex mutex; 66 struct mutex mutex;
67 struct device dev; 67 struct device dev;
68 struct cdev cdev;
68 bool exist; 69 bool exist;
70 bool is_mixdev;
69 71
70 struct list_head mixdev_node; 72 struct list_head mixdev_node;
71 bool opened_by_mixdev; 73 bool opened_by_mixdev;
@@ -111,10 +113,6 @@ struct mousedev_client {
111static unsigned char mousedev_imps_seq[] = { 0xf3, 200, 0xf3, 100, 0xf3, 80 }; 113static unsigned char mousedev_imps_seq[] = { 0xf3, 200, 0xf3, 100, 0xf3, 80 };
112static unsigned char mousedev_imex_seq[] = { 0xf3, 200, 0xf3, 200, 0xf3, 80 }; 114static unsigned char mousedev_imex_seq[] = { 0xf3, 200, 0xf3, 200, 0xf3, 80 };
113 115
114static struct input_handler mousedev_handler;
115
116static struct mousedev *mousedev_table[MOUSEDEV_MINORS];
117static DEFINE_MUTEX(mousedev_table_mutex);
118static struct mousedev *mousedev_mix; 116static struct mousedev *mousedev_mix;
119static LIST_HEAD(mousedev_mix_list); 117static LIST_HEAD(mousedev_mix_list);
120 118
@@ -430,7 +428,7 @@ static int mousedev_open_device(struct mousedev *mousedev)
430 if (retval) 428 if (retval)
431 return retval; 429 return retval;
432 430
433 if (mousedev->minor == MOUSEDEV_MIX) 431 if (mousedev->is_mixdev)
434 mixdev_open_devices(); 432 mixdev_open_devices();
435 else if (!mousedev->exist) 433 else if (!mousedev->exist)
436 retval = -ENODEV; 434 retval = -ENODEV;
@@ -448,7 +446,7 @@ static void mousedev_close_device(struct mousedev *mousedev)
448{ 446{
449 mutex_lock(&mousedev->mutex); 447 mutex_lock(&mousedev->mutex);
450 448
451 if (mousedev->minor == MOUSEDEV_MIX) 449 if (mousedev->is_mixdev)
452 mixdev_close_devices(); 450 mixdev_close_devices();
453 else if (mousedev->exist && !--mousedev->open) 451 else if (mousedev->exist && !--mousedev->open)
454 input_close_device(&mousedev->handle); 452 input_close_device(&mousedev->handle);
@@ -535,35 +533,17 @@ static int mousedev_open(struct inode *inode, struct file *file)
535 struct mousedev_client *client; 533 struct mousedev_client *client;
536 struct mousedev *mousedev; 534 struct mousedev *mousedev;
537 int error; 535 int error;
538 int i;
539 536
540#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX 537#ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
541 if (imajor(inode) == MISC_MAJOR) 538 if (imajor(inode) == MISC_MAJOR)
542 i = MOUSEDEV_MIX; 539 mousedev = mousedev_mix;
543 else 540 else
544#endif 541#endif
545 i = iminor(inode) - MOUSEDEV_MINOR_BASE; 542 mousedev = container_of(inode->i_cdev, struct mousedev, cdev);
546
547 if (i >= MOUSEDEV_MINORS)
548 return -ENODEV;
549
550 error = mutex_lock_interruptible(&mousedev_table_mutex);
551 if (error)
552 return error;
553
554 mousedev = mousedev_table[i];
555 if (mousedev)
556 get_device(&mousedev->dev);
557 mutex_unlock(&mousedev_table_mutex);
558
559 if (!mousedev)
560 return -ENODEV;
561 543
562 client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL); 544 client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL);
563 if (!client) { 545 if (!client)
564 error = -ENOMEM; 546 return -ENOMEM;
565 goto err_put_mousedev;
566 }
567 547
568 spin_lock_init(&client->packet_lock); 548 spin_lock_init(&client->packet_lock);
569 client->pos_x = xres / 2; 549 client->pos_x = xres / 2;
@@ -577,13 +557,13 @@ static int mousedev_open(struct inode *inode, struct file *file)
577 557
578 file->private_data = client; 558 file->private_data = client;
579 nonseekable_open(inode, file); 559 nonseekable_open(inode, file);
560
561 get_device(&mousedev->dev);
580 return 0; 562 return 0;
581 563
582 err_free_client: 564 err_free_client:
583 mousedev_detach_client(mousedev, client); 565 mousedev_detach_client(mousedev, client);
584 kfree(client); 566 kfree(client);
585 err_put_mousedev:
586 put_device(&mousedev->dev);
587 return error; 567 return error;
588} 568}
589 569
@@ -793,19 +773,6 @@ static const struct file_operations mousedev_fops = {
793 .llseek = noop_llseek, 773 .llseek = noop_llseek,
794}; 774};
795 775
796static int mousedev_install_chrdev(struct mousedev *mousedev)
797{
798 mousedev_table[mousedev->minor] = mousedev;
799 return 0;
800}
801
802static void mousedev_remove_chrdev(struct mousedev *mousedev)
803{
804 mutex_lock(&mousedev_table_mutex);
805 mousedev_table[mousedev->minor] = NULL;
806 mutex_unlock(&mousedev_table_mutex);
807}
808
809/* 776/*
810 * Mark device non-existent. This disables writes, ioctls and 777 * Mark device non-existent. This disables writes, ioctls and
811 * prevents new users from opening the device. Already posted 778 * prevents new users from opening the device. Already posted
@@ -840,24 +807,50 @@ static void mousedev_cleanup(struct mousedev *mousedev)
840 807
841 mousedev_mark_dead(mousedev); 808 mousedev_mark_dead(mousedev);
842 mousedev_hangup(mousedev); 809 mousedev_hangup(mousedev);
843 mousedev_remove_chrdev(mousedev); 810
811 cdev_del(&mousedev->cdev);
844 812
845 /* mousedev is marked dead so no one else accesses mousedev->open */ 813 /* mousedev is marked dead so no one else accesses mousedev->open */
846 if (mousedev->open) 814 if (mousedev->open)
847 input_close_device(handle); 815 input_close_device(handle);
848} 816}
849 817
818static int mousedev_reserve_minor(bool mixdev)
819{
820 int minor;
821
822 if (mixdev) {
823 minor = input_get_new_minor(MOUSEDEV_MIX, 1, false);
824 if (minor < 0)
825 pr_err("failed to reserve mixdev minor: %d\n", minor);
826 } else {
827 minor = input_get_new_minor(MOUSEDEV_MINOR_BASE,
828 MOUSEDEV_MINORS, true);
829 if (minor < 0)
830 pr_err("failed to reserve new minor: %d\n", minor);
831 }
832
833 return minor;
834}
835
850static struct mousedev *mousedev_create(struct input_dev *dev, 836static struct mousedev *mousedev_create(struct input_dev *dev,
851 struct input_handler *handler, 837 struct input_handler *handler,
852 int minor) 838 bool mixdev)
853{ 839{
854 struct mousedev *mousedev; 840 struct mousedev *mousedev;
841 int minor;
855 int error; 842 int error;
856 843
844 minor = mousedev_reserve_minor(mixdev);
845 if (minor < 0) {
846 error = minor;
847 goto err_out;
848 }
849
857 mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL); 850 mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL);
858 if (!mousedev) { 851 if (!mousedev) {
859 error = -ENOMEM; 852 error = -ENOMEM;
860 goto err_out; 853 goto err_free_minor;
861 } 854 }
862 855
863 INIT_LIST_HEAD(&mousedev->client_list); 856 INIT_LIST_HEAD(&mousedev->client_list);
@@ -865,16 +858,21 @@ static struct mousedev *mousedev_create(struct input_dev *dev,
865 spin_lock_init(&mousedev->client_lock); 858 spin_lock_init(&mousedev->client_lock);
866 mutex_init(&mousedev->mutex); 859 mutex_init(&mousedev->mutex);
867 lockdep_set_subclass(&mousedev->mutex, 860 lockdep_set_subclass(&mousedev->mutex,
868 minor == MOUSEDEV_MIX ? SINGLE_DEPTH_NESTING : 0); 861 mixdev ? SINGLE_DEPTH_NESTING : 0);
869 init_waitqueue_head(&mousedev->wait); 862 init_waitqueue_head(&mousedev->wait);
870 863
871 if (minor == MOUSEDEV_MIX) 864 if (mixdev) {
872 dev_set_name(&mousedev->dev, "mice"); 865 dev_set_name(&mousedev->dev, "mice");
873 else 866 } else {
874 dev_set_name(&mousedev->dev, "mouse%d", minor); 867 int dev_no = minor;
868 /* Normalize device number if it falls into legacy range */
869 if (dev_no < MOUSEDEV_MINOR_BASE + MOUSEDEV_MINORS)
870 dev_no -= MOUSEDEV_MINOR_BASE;
871 dev_set_name(&mousedev->dev, "mouse%d", dev_no);
872 }
875 873
876 mousedev->minor = minor;
877 mousedev->exist = true; 874 mousedev->exist = true;
875 mousedev->is_mixdev = mixdev;
878 mousedev->handle.dev = input_get_device(dev); 876 mousedev->handle.dev = input_get_device(dev);
879 mousedev->handle.name = dev_name(&mousedev->dev); 877 mousedev->handle.name = dev_name(&mousedev->dev);
880 mousedev->handle.handler = handler; 878 mousedev->handle.handler = handler;
@@ -883,17 +881,18 @@ static struct mousedev *mousedev_create(struct input_dev *dev,
883 mousedev->dev.class = &input_class; 881 mousedev->dev.class = &input_class;
884 if (dev) 882 if (dev)
885 mousedev->dev.parent = &dev->dev; 883 mousedev->dev.parent = &dev->dev;
886 mousedev->dev.devt = MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor); 884 mousedev->dev.devt = MKDEV(INPUT_MAJOR, minor);
887 mousedev->dev.release = mousedev_free; 885 mousedev->dev.release = mousedev_free;
888 device_initialize(&mousedev->dev); 886 device_initialize(&mousedev->dev);
889 887
890 if (minor != MOUSEDEV_MIX) { 888 if (!mixdev) {
891 error = input_register_handle(&mousedev->handle); 889 error = input_register_handle(&mousedev->handle);
892 if (error) 890 if (error)
893 goto err_free_mousedev; 891 goto err_free_mousedev;
894 } 892 }
895 893
896 error = mousedev_install_chrdev(mousedev); 894 cdev_init(&mousedev->cdev, &mousedev_fops);
895 error = cdev_add(&mousedev->cdev, mousedev->dev.devt, 1);
897 if (error) 896 if (error)
898 goto err_unregister_handle; 897 goto err_unregister_handle;
899 898
@@ -906,10 +905,12 @@ static struct mousedev *mousedev_create(struct input_dev *dev,
906 err_cleanup_mousedev: 905 err_cleanup_mousedev:
907 mousedev_cleanup(mousedev); 906 mousedev_cleanup(mousedev);
908 err_unregister_handle: 907 err_unregister_handle:
909 if (minor != MOUSEDEV_MIX) 908 if (!mixdev)
910 input_unregister_handle(&mousedev->handle); 909 input_unregister_handle(&mousedev->handle);
911 err_free_mousedev: 910 err_free_mousedev:
912 put_device(&mousedev->dev); 911 put_device(&mousedev->dev);
912 err_free_minor:
913 input_free_minor(minor);
913 err_out: 914 err_out:
914 return ERR_PTR(error); 915 return ERR_PTR(error);
915} 916}
@@ -918,7 +919,8 @@ static void mousedev_destroy(struct mousedev *mousedev)
918{ 919{
919 device_del(&mousedev->dev); 920 device_del(&mousedev->dev);
920 mousedev_cleanup(mousedev); 921 mousedev_cleanup(mousedev);
921 if (mousedev->minor != MOUSEDEV_MIX) 922 input_free_minor(MINOR(mousedev->dev.devt));
923 if (!mousedev->is_mixdev)
922 input_unregister_handle(&mousedev->handle); 924 input_unregister_handle(&mousedev->handle);
923 put_device(&mousedev->dev); 925 put_device(&mousedev->dev);
924} 926}
@@ -967,19 +969,9 @@ static int mousedev_connect(struct input_handler *handler,
967 const struct input_device_id *id) 969 const struct input_device_id *id)
968{ 970{
969 struct mousedev *mousedev; 971 struct mousedev *mousedev;
970 int minor;
971 int error; 972 int error;
972 973
973 for (minor = 0; minor < MOUSEDEV_MINORS; minor++) 974 mousedev = mousedev_create(dev, handler, false);
974 if (!mousedev_table[minor])
975 break;
976
977 if (minor == MOUSEDEV_MINORS) {
978 pr_err("no more free mousedev devices\n");
979 return -ENFILE;
980 }
981
982 mousedev = mousedev_create(dev, handler, minor);
983 if (IS_ERR(mousedev)) 975 if (IS_ERR(mousedev))
984 return PTR_ERR(mousedev); 976 return PTR_ERR(mousedev);
985 977
@@ -1055,7 +1047,7 @@ static struct input_handler mousedev_handler = {
1055 .event = mousedev_event, 1047 .event = mousedev_event,
1056 .connect = mousedev_connect, 1048 .connect = mousedev_connect,
1057 .disconnect = mousedev_disconnect, 1049 .disconnect = mousedev_disconnect,
1058 .fops = &mousedev_fops, 1050 .legacy_minors = true,
1059 .minor = MOUSEDEV_MINOR_BASE, 1051 .minor = MOUSEDEV_MINOR_BASE,
1060 .name = "mousedev", 1052 .name = "mousedev",
1061 .id_table = mousedev_ids, 1053 .id_table = mousedev_ids,
@@ -1098,7 +1090,7 @@ static int __init mousedev_init(void)
1098{ 1090{
1099 int error; 1091 int error;
1100 1092
1101 mousedev_mix = mousedev_create(NULL, &mousedev_handler, MOUSEDEV_MIX); 1093 mousedev_mix = mousedev_create(NULL, &mousedev_handler, true);
1102 if (IS_ERR(mousedev_mix)) 1094 if (IS_ERR(mousedev_mix))
1103 return PTR_ERR(mousedev_mix); 1095 return PTR_ERR(mousedev_mix);
1104 1096
diff --git a/include/linux/input.h b/include/linux/input.h
index ba4874302939..15464ba6bf53 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -1396,8 +1396,8 @@ struct input_handle;
1396 * @start: starts handler for given handle. This function is called by 1396 * @start: starts handler for given handle. This function is called by
1397 * input core right after connect() method and also when a process 1397 * input core right after connect() method and also when a process
1398 * that "grabbed" a device releases it 1398 * that "grabbed" a device releases it
1399 * @fops: file operations this driver implements 1399 * @legacy_minors: set to %true by drivers using legacy minor ranges
1400 * @minor: beginning of range of 32 minors for devices this driver 1400 * @minor: beginning of range of 32 legacy minors for devices this driver
1401 * can provide 1401 * can provide
1402 * @name: name of the handler, to be shown in /proc/bus/input/handlers 1402 * @name: name of the handler, to be shown in /proc/bus/input/handlers
1403 * @id_table: pointer to a table of input_device_ids this driver can 1403 * @id_table: pointer to a table of input_device_ids this driver can
@@ -1431,7 +1431,7 @@ struct input_handler {
1431 void (*disconnect)(struct input_handle *handle); 1431 void (*disconnect)(struct input_handle *handle);
1432 void (*start)(struct input_handle *handle); 1432 void (*start)(struct input_handle *handle);
1433 1433
1434 const struct file_operations *fops; 1434 bool legacy_minors;
1435 int minor; 1435 int minor;
1436 const char *name; 1436 const char *name;
1437 1437
@@ -1499,6 +1499,10 @@ void input_reset_device(struct input_dev *);
1499int __must_check input_register_handler(struct input_handler *); 1499int __must_check input_register_handler(struct input_handler *);
1500void input_unregister_handler(struct input_handler *); 1500void input_unregister_handler(struct input_handler *);
1501 1501
1502int __must_check input_get_new_minor(int legacy_base, unsigned int legacy_num,
1503 bool allow_dynamic);
1504void input_free_minor(unsigned int minor);
1505
1502int input_handler_for_each_handle(struct input_handler *, void *data, 1506int input_handler_for_each_handle(struct input_handler *, void *data,
1503 int (*fn)(struct input_handle *, void *)); 1507 int (*fn)(struct input_handle *, void *));
1504 1508