be6b93c20f606b9e477746e81688d7abe25bcdda
[linux-2.6.git] / drivers / input / evdev.c
1 /*
2  * Event char devices, giving access to raw input device events.
3  *
4  * Copyright (c) 1999-2002 Vojtech Pavlik
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 as published by
8  * the Free Software Foundation.
9  */
10
11 #define EVDEV_MINOR_BASE        64
12 #define EVDEV_MINORS            32
13 #define EVDEV_BUFFER_SIZE       64
14
15 #include <linux/poll.h>
16 #include <linux/slab.h>
17 #include <linux/module.h>
18 #include <linux/init.h>
19 #include <linux/input.h>
20 #include <linux/major.h>
21 #include <linux/device.h>
22 #include <linux/compat.h>
23
24 struct evdev {
25         int exist;
26         int open;
27         int minor;
28         char name[16];
29         struct input_handle handle;
30         wait_queue_head_t wait;
31         struct evdev_client *grab;
32         struct list_head client_list;
33 };
34
35 struct evdev_client {
36         struct input_event buffer[EVDEV_BUFFER_SIZE];
37         int head;
38         int tail;
39         struct fasync_struct *fasync;
40         struct evdev *evdev;
41         struct list_head node;
42 };
43
44 static struct evdev *evdev_table[EVDEV_MINORS];
45
46 static void evdev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
47 {
48         struct evdev *evdev = handle->private;
49         struct evdev_client *client;
50
51         if (evdev->grab) {
52                 client = evdev->grab;
53
54                 do_gettimeofday(&client->buffer[client->head].time);
55                 client->buffer[client->head].type = type;
56                 client->buffer[client->head].code = code;
57                 client->buffer[client->head].value = value;
58                 client->head = (client->head + 1) & (EVDEV_BUFFER_SIZE - 1);
59
60                 kill_fasync(&client->fasync, SIGIO, POLL_IN);
61         } else
62                 list_for_each_entry(client, &evdev->client_list, node) {
63
64                         do_gettimeofday(&client->buffer[client->head].time);
65                         client->buffer[client->head].type = type;
66                         client->buffer[client->head].code = code;
67                         client->buffer[client->head].value = value;
68                         client->head = (client->head + 1) & (EVDEV_BUFFER_SIZE - 1);
69
70                         kill_fasync(&client->fasync, SIGIO, POLL_IN);
71                 }
72
73         wake_up_interruptible(&evdev->wait);
74 }
75
76 static int evdev_fasync(int fd, struct file *file, int on)
77 {
78         struct evdev_client *client = file->private_data;
79         int retval;
80
81         retval = fasync_helper(fd, file, on, &client->fasync);
82
83         return retval < 0 ? retval : 0;
84 }
85
86 static int evdev_flush(struct file *file, fl_owner_t id)
87 {
88         struct evdev_client *client = file->private_data;
89         struct evdev *evdev = client->evdev;
90
91         if (!evdev->exist)
92                 return -ENODEV;
93
94         return input_flush_device(&evdev->handle, file);
95 }
96
97 static void evdev_free(struct evdev *evdev)
98 {
99         evdev_table[evdev->minor] = NULL;
100         kfree(evdev);
101 }
102
103 static int evdev_release(struct inode *inode, struct file *file)
104 {
105         struct evdev_client *client = file->private_data;
106         struct evdev *evdev = client->evdev;
107
108         if (evdev->grab == client) {
109                 input_release_device(&evdev->handle);
110                 evdev->grab = NULL;
111         }
112
113         evdev_fasync(-1, file, 0);
114         list_del(&client->node);
115         kfree(client);
116
117         if (!--evdev->open) {
118                 if (evdev->exist)
119                         input_close_device(&evdev->handle);
120                 else
121                         evdev_free(evdev);
122         }
123
124         return 0;
125 }
126
127 static int evdev_open(struct inode *inode, struct file *file)
128 {
129         struct evdev_client *client;
130         struct evdev *evdev;
131         int i = iminor(inode) - EVDEV_MINOR_BASE;
132         int error;
133
134         if (i >= EVDEV_MINORS)
135                 return -ENODEV;
136
137         evdev = evdev_table[i];
138
139         if (!evdev || !evdev->exist)
140                 return -ENODEV;
141
142         client = kzalloc(sizeof(struct evdev_client), GFP_KERNEL);
143         if (!client)
144                 return -ENOMEM;
145
146         client->evdev = evdev;
147         list_add_tail(&client->node, &evdev->client_list);
148
149         if (!evdev->open++ && evdev->exist) {
150                 error = input_open_device(&evdev->handle);
151                 if (error) {
152                         list_del(&client->node);
153                         kfree(client);
154                         return error;
155                 }
156         }
157
158         file->private_data = client;
159         return 0;
160 }
161
162 #ifdef CONFIG_COMPAT
163
164 struct input_event_compat {
165         struct compat_timeval time;
166         __u16 type;
167         __u16 code;
168         __s32 value;
169 };
170
171 /* Note to the author of this code: did it ever occur to
172    you why the ifdefs are needed? Think about it again. -AK */
173 #ifdef CONFIG_X86_64
174 #  define COMPAT_TEST is_compat_task()
175 #elif defined(CONFIG_IA64)
176 #  define COMPAT_TEST IS_IA32_PROCESS(task_pt_regs(current))
177 #elif defined(CONFIG_S390)
178 #  define COMPAT_TEST test_thread_flag(TIF_31BIT)
179 #elif defined(CONFIG_MIPS)
180 #  define COMPAT_TEST (current->thread.mflags & MF_32BIT_ADDR)
181 #else
182 #  define COMPAT_TEST test_thread_flag(TIF_32BIT)
183 #endif
184
185 static inline size_t evdev_event_size(void)
186 {
187         return COMPAT_TEST ?
188                 sizeof(struct input_event_compat) : sizeof(struct input_event);
189 }
190
191 static int evdev_event_from_user(const char __user *buffer, struct input_event *event)
192 {
193         if (COMPAT_TEST) {
194                 struct input_event_compat compat_event;
195
196                 if (copy_from_user(&compat_event, buffer, sizeof(struct input_event_compat)))
197                         return -EFAULT;
198
199                 event->time.tv_sec = compat_event.time.tv_sec;
200                 event->time.tv_usec = compat_event.time.tv_usec;
201                 event->type = compat_event.type;
202                 event->code = compat_event.code;
203                 event->value = compat_event.value;
204
205         } else {
206                 if (copy_from_user(event, buffer, sizeof(struct input_event)))
207                         return -EFAULT;
208         }
209
210         return 0;
211 }
212
213 static int evdev_event_to_user(char __user *buffer, const struct input_event *event)
214 {
215         if (COMPAT_TEST) {
216                 struct input_event_compat compat_event;
217
218                 compat_event.time.tv_sec = event->time.tv_sec;
219                 compat_event.time.tv_usec = event->time.tv_usec;
220                 compat_event.type = event->type;
221                 compat_event.code = event->code;
222                 compat_event.value = event->value;
223
224                 if (copy_to_user(buffer, &compat_event, sizeof(struct input_event_compat)))
225                         return -EFAULT;
226
227         } else {
228                 if (copy_to_user(buffer, event, sizeof(struct input_event)))
229                         return -EFAULT;
230         }
231
232         return 0;
233 }
234
235 #else
236
237 static inline size_t evdev_event_size(void)
238 {
239         return sizeof(struct input_event);
240 }
241
242 static int evdev_event_from_user(const char __user *buffer, struct input_event *event)
243 {
244         if (copy_from_user(event, buffer, sizeof(struct input_event)))
245                 return -EFAULT;
246
247         return 0;
248 }
249
250 static int evdev_event_to_user(char __user *buffer, const struct input_event *event)
251 {
252         if (copy_to_user(buffer, event, sizeof(struct input_event)))
253                 return -EFAULT;
254
255         return 0;
256 }
257
258 #endif /* CONFIG_COMPAT */
259
260 static ssize_t evdev_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
261 {
262         struct evdev_client *client = file->private_data;
263         struct evdev *evdev = client->evdev;
264         struct input_event event;
265         int retval = 0;
266
267         if (!evdev->exist)
268                 return -ENODEV;
269
270         while (retval < count) {
271
272                 if (evdev_event_from_user(buffer + retval, &event))
273                         return -EFAULT;
274                 input_inject_event(&evdev->handle, event.type, event.code, event.value);
275                 retval += evdev_event_size();
276         }
277
278         return retval;
279 }
280
281 static ssize_t evdev_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
282 {
283         struct evdev_client *client = file->private_data;
284         struct evdev *evdev = client->evdev;
285         int retval;
286
287         if (count < evdev_event_size())
288                 return -EINVAL;
289
290         if (client->head == client->tail && evdev->exist && (file->f_flags & O_NONBLOCK))
291                 return -EAGAIN;
292
293         retval = wait_event_interruptible(evdev->wait,
294                 client->head != client->tail || !evdev->exist);
295         if (retval)
296                 return retval;
297
298         if (!evdev->exist)
299                 return -ENODEV;
300
301         while (client->head != client->tail && retval + evdev_event_size() <= count) {
302
303                 struct input_event *event = (struct input_event *) client->buffer + client->tail;
304
305                 if (evdev_event_to_user(buffer + retval, event))
306                         return -EFAULT;
307
308                 client->tail = (client->tail + 1) & (EVDEV_BUFFER_SIZE - 1);
309                 retval += evdev_event_size();
310         }
311
312         return retval;
313 }
314
315 /* No kernel lock - fine */
316 static unsigned int evdev_poll(struct file *file, poll_table *wait)
317 {
318         struct evdev_client *client = file->private_data;
319         struct evdev *evdev = client->evdev;
320
321         poll_wait(file, &evdev->wait, wait);
322         return ((client->head == client->tail) ? 0 : (POLLIN | POLLRDNORM)) |
323                 (evdev->exist ? 0 : (POLLHUP | POLLERR));
324 }
325
326 #ifdef CONFIG_COMPAT
327
328 #define BITS_PER_LONG_COMPAT (sizeof(compat_long_t) * 8)
329 #define NBITS_COMPAT(x) ((((x) - 1) / BITS_PER_LONG_COMPAT) + 1)
330
331 #ifdef __BIG_ENDIAN
332 static int bits_to_user(unsigned long *bits, unsigned int maxbit,
333                         unsigned int maxlen, void __user *p, int compat)
334 {
335         int len, i;
336
337         if (compat) {
338                 len = NBITS_COMPAT(maxbit) * sizeof(compat_long_t);
339                 if (len > maxlen)
340                         len = maxlen;
341
342                 for (i = 0; i < len / sizeof(compat_long_t); i++)
343                         if (copy_to_user((compat_long_t __user *) p + i,
344                                          (compat_long_t *) bits +
345                                                 i + 1 - ((i % 2) << 1),
346                                          sizeof(compat_long_t)))
347                                 return -EFAULT;
348         } else {
349                 len = NBITS(maxbit) * sizeof(long);
350                 if (len > maxlen)
351                         len = maxlen;
352
353                 if (copy_to_user(p, bits, len))
354                         return -EFAULT;
355         }
356
357         return len;
358 }
359 #else
360 static int bits_to_user(unsigned long *bits, unsigned int maxbit,
361                         unsigned int maxlen, void __user *p, int compat)
362 {
363         int len = compat ?
364                         NBITS_COMPAT(maxbit) * sizeof(compat_long_t) :
365                         NBITS(maxbit) * sizeof(long);
366
367         if (len > maxlen)
368                 len = maxlen;
369
370         return copy_to_user(p, bits, len) ? -EFAULT : len;
371 }
372 #endif /* __BIG_ENDIAN */
373
374 #else
375
376 static int bits_to_user(unsigned long *bits, unsigned int maxbit,
377                         unsigned int maxlen, void __user *p, int compat)
378 {
379         int len = NBITS(maxbit) * sizeof(long);
380
381         if (len > maxlen)
382                 len = maxlen;
383
384         return copy_to_user(p, bits, len) ? -EFAULT : len;
385 }
386
387 #endif /* CONFIG_COMPAT */
388
389 static int str_to_user(const char *str, unsigned int maxlen, void __user *p)
390 {
391         int len;
392
393         if (!str)
394                 return -ENOENT;
395
396         len = strlen(str) + 1;
397         if (len > maxlen)
398                 len = maxlen;
399
400         return copy_to_user(p, str, len) ? -EFAULT : len;
401 }
402
403 static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
404                                 void __user *p, int compat_mode)
405 {
406         struct evdev_client *client = file->private_data;
407         struct evdev *evdev = client->evdev;
408         struct input_dev *dev = evdev->handle.dev;
409         struct input_absinfo abs;
410         struct ff_effect effect;
411         int __user *ip = (int __user *)p;
412         int i, t, u, v;
413         int error;
414
415         if (!evdev->exist)
416                 return -ENODEV;
417
418         switch (cmd) {
419
420                 case EVIOCGVERSION:
421                         return put_user(EV_VERSION, ip);
422
423                 case EVIOCGID:
424                         if (copy_to_user(p, &dev->id, sizeof(struct input_id)))
425                                 return -EFAULT;
426                         return 0;
427
428                 case EVIOCGREP:
429                         if (!test_bit(EV_REP, dev->evbit))
430                                 return -ENOSYS;
431                         if (put_user(dev->rep[REP_DELAY], ip))
432                                 return -EFAULT;
433                         if (put_user(dev->rep[REP_PERIOD], ip + 1))
434                                 return -EFAULT;
435                         return 0;
436
437                 case EVIOCSREP:
438                         if (!test_bit(EV_REP, dev->evbit))
439                                 return -ENOSYS;
440                         if (get_user(u, ip))
441                                 return -EFAULT;
442                         if (get_user(v, ip + 1))
443                                 return -EFAULT;
444
445                         input_inject_event(&evdev->handle, EV_REP, REP_DELAY, u);
446                         input_inject_event(&evdev->handle, EV_REP, REP_PERIOD, v);
447
448                         return 0;
449
450                 case EVIOCGKEYCODE:
451                         if (get_user(t, ip))
452                                 return -EFAULT;
453
454                         error = dev->getkeycode(dev, t, &v);
455                         if (error)
456                                 return error;
457
458                         if (put_user(v, ip + 1))
459                                 return -EFAULT;
460
461                         return 0;
462
463                 case EVIOCSKEYCODE:
464                         if (get_user(t, ip) || get_user(v, ip + 1))
465                                 return -EFAULT;
466
467                         return dev->setkeycode(dev, t, v);
468
469                 case EVIOCSFF:
470                         if (copy_from_user(&effect, p, sizeof(effect)))
471                                 return -EFAULT;
472
473                         error = input_ff_upload(dev, &effect, file);
474
475                         if (put_user(effect.id, &(((struct ff_effect __user *)p)->id)))
476                                 return -EFAULT;
477
478                         return error;
479
480                 case EVIOCRMFF:
481                         return input_ff_erase(dev, (int)(unsigned long) p, file);
482
483                 case EVIOCGEFFECTS:
484                         i = test_bit(EV_FF, dev->evbit) ? dev->ff->max_effects : 0;
485                         if (put_user(i, ip))
486                                 return -EFAULT;
487                         return 0;
488
489                 case EVIOCGRAB:
490                         if (p) {
491                                 if (evdev->grab)
492                                         return -EBUSY;
493                                 if (input_grab_device(&evdev->handle))
494                                         return -EBUSY;
495                                 evdev->grab = client;
496                                 return 0;
497                         } else {
498                                 if (evdev->grab != client)
499                                         return -EINVAL;
500                                 input_release_device(&evdev->handle);
501                                 evdev->grab = NULL;
502                                 return 0;
503                         }
504
505                 default:
506
507                         if (_IOC_TYPE(cmd) != 'E')
508                                 return -EINVAL;
509
510                         if (_IOC_DIR(cmd) == _IOC_READ) {
511
512                                 if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0,0))) {
513
514                                         unsigned long *bits;
515                                         int len;
516
517                                         switch (_IOC_NR(cmd) & EV_MAX) {
518                                                 case      0: bits = dev->evbit;  len = EV_MAX;  break;
519                                                 case EV_KEY: bits = dev->keybit; len = KEY_MAX; break;
520                                                 case EV_REL: bits = dev->relbit; len = REL_MAX; break;
521                                                 case EV_ABS: bits = dev->absbit; len = ABS_MAX; break;
522                                                 case EV_MSC: bits = dev->mscbit; len = MSC_MAX; break;
523                                                 case EV_LED: bits = dev->ledbit; len = LED_MAX; break;
524                                                 case EV_SND: bits = dev->sndbit; len = SND_MAX; break;
525                                                 case EV_FF:  bits = dev->ffbit;  len = FF_MAX;  break;
526                                                 case EV_SW:  bits = dev->swbit;  len = SW_MAX;  break;
527                                                 default: return -EINVAL;
528                                         }
529                                         return bits_to_user(bits, len, _IOC_SIZE(cmd), p, compat_mode);
530                                 }
531
532                                 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0)))
533                                         return bits_to_user(dev->key, KEY_MAX, _IOC_SIZE(cmd),
534                                                             p, compat_mode);
535
536                                 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0)))
537                                         return bits_to_user(dev->led, LED_MAX, _IOC_SIZE(cmd),
538                                                             p, compat_mode);
539
540                                 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0)))
541                                         return bits_to_user(dev->snd, SND_MAX, _IOC_SIZE(cmd),
542                                                             p, compat_mode);
543
544                                 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSW(0)))
545                                         return bits_to_user(dev->sw, SW_MAX, _IOC_SIZE(cmd),
546                                                             p, compat_mode);
547
548                                 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0)))
549                                         return str_to_user(dev->name, _IOC_SIZE(cmd), p);
550
551                                 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0)))
552                                         return str_to_user(dev->phys, _IOC_SIZE(cmd), p);
553
554                                 if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0)))
555                                         return str_to_user(dev->uniq, _IOC_SIZE(cmd), p);
556
557                                 if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
558
559                                         t = _IOC_NR(cmd) & ABS_MAX;
560
561                                         abs.value = dev->abs[t];
562                                         abs.minimum = dev->absmin[t];
563                                         abs.maximum = dev->absmax[t];
564                                         abs.fuzz = dev->absfuzz[t];
565                                         abs.flat = dev->absflat[t];
566
567                                         if (copy_to_user(p, &abs, sizeof(struct input_absinfo)))
568                                                 return -EFAULT;
569
570                                         return 0;
571                                 }
572
573                         }
574
575                         if (_IOC_DIR(cmd) == _IOC_WRITE) {
576
577                                 if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) {
578
579                                         t = _IOC_NR(cmd) & ABS_MAX;
580
581                                         if (copy_from_user(&abs, p, sizeof(struct input_absinfo)))
582                                                 return -EFAULT;
583
584                                         dev->abs[t] = abs.value;
585                                         dev->absmin[t] = abs.minimum;
586                                         dev->absmax[t] = abs.maximum;
587                                         dev->absfuzz[t] = abs.fuzz;
588                                         dev->absflat[t] = abs.flat;
589
590                                         return 0;
591                                 }
592                         }
593         }
594         return -EINVAL;
595 }
596
597 static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
598 {
599         return evdev_ioctl_handler(file, cmd, (void __user *)arg, 0);
600 }
601
602 #ifdef CONFIG_COMPAT
603 static long evdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
604 {
605         return evdev_ioctl_handler(file, cmd, compat_ptr(arg), 1);
606 }
607 #endif
608
609 static const struct file_operations evdev_fops = {
610         .owner =        THIS_MODULE,
611         .read =         evdev_read,
612         .write =        evdev_write,
613         .poll =         evdev_poll,
614         .open =         evdev_open,
615         .release =      evdev_release,
616         .unlocked_ioctl = evdev_ioctl,
617 #ifdef CONFIG_COMPAT
618         .compat_ioctl = evdev_ioctl_compat,
619 #endif
620         .fasync =       evdev_fasync,
621         .flush =        evdev_flush
622 };
623
624 static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
625                          const struct input_device_id *id)
626 {
627         struct evdev *evdev;
628         struct class_device *cdev;
629         dev_t devt;
630         int minor;
631         int error;
632
633         for (minor = 0; minor < EVDEV_MINORS && evdev_table[minor]; minor++);
634         if (minor == EVDEV_MINORS) {
635                 printk(KERN_ERR "evdev: no more free evdev devices\n");
636                 return -ENFILE;
637         }
638
639         evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL);
640         if (!evdev)
641                 return -ENOMEM;
642
643         INIT_LIST_HEAD(&evdev->client_list);
644         init_waitqueue_head(&evdev->wait);
645
646         evdev->exist = 1;
647         evdev->minor = minor;
648         evdev->handle.dev = dev;
649         evdev->handle.name = evdev->name;
650         evdev->handle.handler = handler;
651         evdev->handle.private = evdev;
652         sprintf(evdev->name, "event%d", minor);
653
654         evdev_table[minor] = evdev;
655
656         devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
657
658         cdev = class_device_create(&input_class, &dev->cdev, devt,
659                                    dev->cdev.dev, evdev->name);
660         if (IS_ERR(cdev)) {
661                 error = PTR_ERR(cdev);
662                 goto err_free_evdev;
663         }
664
665         /* temporary symlink to keep userspace happy */
666         error = sysfs_create_link(&input_class.subsys.kobj,
667                                   &cdev->kobj, evdev->name);
668         if (error)
669                 goto err_cdev_destroy;
670
671         error = input_register_handle(&evdev->handle);
672         if (error)
673                 goto err_remove_link;
674
675         return 0;
676
677  err_remove_link:
678         sysfs_remove_link(&input_class.subsys.kobj, evdev->name);
679  err_cdev_destroy:
680         class_device_destroy(&input_class, devt);
681  err_free_evdev:
682         kfree(evdev);
683         evdev_table[minor] = NULL;
684         return error;
685 }
686
687 static void evdev_disconnect(struct input_handle *handle)
688 {
689         struct evdev *evdev = handle->private;
690         struct evdev_client *client;
691
692         input_unregister_handle(handle);
693
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;
698
699         if (evdev->open) {
700                 input_flush_device(handle, NULL);
701                 input_close_device(handle);
702                 list_for_each_entry(client, &evdev->client_list, node)
703                         kill_fasync(&client->fasync, SIGIO, POLL_HUP);
704                 wake_up_interruptible(&evdev->wait);
705         } else
706                 evdev_free(evdev);
707 }
708
709 static const struct input_device_id evdev_ids[] = {
710         { .driver_info = 1 },   /* Matches all devices */
711         { },                    /* Terminating zero entry */
712 };
713
714 MODULE_DEVICE_TABLE(input, evdev_ids);
715
716 static struct input_handler evdev_handler = {
717         .event =        evdev_event,
718         .connect =      evdev_connect,
719         .disconnect =   evdev_disconnect,
720         .fops =         &evdev_fops,
721         .minor =        EVDEV_MINOR_BASE,
722         .name =         "evdev",
723         .id_table =     evdev_ids,
724 };
725
726 static int __init evdev_init(void)
727 {
728         return input_register_handler(&evdev_handler);
729 }
730
731 static void __exit evdev_exit(void)
732 {
733         input_unregister_handler(&evdev_handler);
734 }
735
736 module_init(evdev_init);
737 module_exit(evdev_exit);
738
739 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
740 MODULE_DESCRIPTION("Input driver event char devices");
741 MODULE_LICENSE("GPL");