.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * The input core |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (c) 1999-2002 Vojtech Pavlik |
---|
5 | 6 | */ |
---|
6 | 7 | |
---|
7 | | -/* |
---|
8 | | - * This program is free software; you can redistribute it and/or modify it |
---|
9 | | - * under the terms of the GNU General Public License version 2 as published by |
---|
10 | | - * the Free Software Foundation. |
---|
11 | | - */ |
---|
12 | 8 | |
---|
13 | 9 | #define pr_fmt(fmt) KBUILD_BASENAME ": " fmt |
---|
14 | 10 | |
---|
.. | .. |
---|
28 | 24 | #include <linux/mutex.h> |
---|
29 | 25 | #include <linux/rcupdate.h> |
---|
30 | 26 | #include "input-compat.h" |
---|
| 27 | +#include "input-poller.h" |
---|
31 | 28 | |
---|
32 | 29 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); |
---|
33 | 30 | MODULE_DESCRIPTION("Input core"); |
---|
.. | .. |
---|
49 | 46 | static DEFINE_MUTEX(input_mutex); |
---|
50 | 47 | |
---|
51 | 48 | static const struct input_value input_value_sync = { EV_SYN, SYN_REPORT, 1 }; |
---|
| 49 | + |
---|
| 50 | +static const unsigned int input_max_code[EV_CNT] = { |
---|
| 51 | + [EV_KEY] = KEY_MAX, |
---|
| 52 | + [EV_REL] = REL_MAX, |
---|
| 53 | + [EV_ABS] = ABS_MAX, |
---|
| 54 | + [EV_MSC] = MSC_MAX, |
---|
| 55 | + [EV_SW] = SW_MAX, |
---|
| 56 | + [EV_LED] = LED_MAX, |
---|
| 57 | + [EV_SND] = SND_MAX, |
---|
| 58 | + [EV_FF] = FF_MAX, |
---|
| 59 | +}; |
---|
52 | 60 | |
---|
53 | 61 | static inline int is_event_supported(unsigned int code, |
---|
54 | 62 | unsigned long *bm, unsigned int max) |
---|
.. | .. |
---|
615 | 623 | |
---|
616 | 624 | handle->open++; |
---|
617 | 625 | |
---|
618 | | - if (!dev->users++ && dev->open) |
---|
619 | | - retval = dev->open(dev); |
---|
| 626 | + if (dev->users++) { |
---|
| 627 | + /* |
---|
| 628 | + * Device is already opened, so we can exit immediately and |
---|
| 629 | + * report success. |
---|
| 630 | + */ |
---|
| 631 | + goto out; |
---|
| 632 | + } |
---|
620 | 633 | |
---|
621 | | - if (retval) { |
---|
622 | | - dev->users--; |
---|
623 | | - if (!--handle->open) { |
---|
| 634 | + if (dev->open) { |
---|
| 635 | + retval = dev->open(dev); |
---|
| 636 | + if (retval) { |
---|
| 637 | + dev->users--; |
---|
| 638 | + handle->open--; |
---|
624 | 639 | /* |
---|
625 | 640 | * Make sure we are not delivering any more events |
---|
626 | 641 | * through this handle |
---|
627 | 642 | */ |
---|
628 | 643 | synchronize_rcu(); |
---|
| 644 | + goto out; |
---|
629 | 645 | } |
---|
630 | 646 | } |
---|
| 647 | + |
---|
| 648 | + if (dev->poller) |
---|
| 649 | + input_dev_poller_start(dev->poller); |
---|
631 | 650 | |
---|
632 | 651 | out: |
---|
633 | 652 | mutex_unlock(&dev->mutex); |
---|
.. | .. |
---|
667 | 686 | |
---|
668 | 687 | __input_release_device(handle); |
---|
669 | 688 | |
---|
670 | | - if (!--dev->users && dev->close) |
---|
671 | | - dev->close(dev); |
---|
| 689 | + if (!--dev->users) { |
---|
| 690 | + if (dev->poller) |
---|
| 691 | + input_dev_poller_stop(dev->poller); |
---|
| 692 | + |
---|
| 693 | + if (dev->close) |
---|
| 694 | + dev->close(dev); |
---|
| 695 | + } |
---|
672 | 696 | |
---|
673 | 697 | if (!--handle->open) { |
---|
674 | 698 | /* |
---|
.. | .. |
---|
1204 | 1228 | return seq_open(file, &input_devices_seq_ops); |
---|
1205 | 1229 | } |
---|
1206 | 1230 | |
---|
1207 | | -static const struct file_operations input_devices_fileops = { |
---|
1208 | | - .owner = THIS_MODULE, |
---|
1209 | | - .open = input_proc_devices_open, |
---|
1210 | | - .poll = input_proc_devices_poll, |
---|
1211 | | - .read = seq_read, |
---|
1212 | | - .llseek = seq_lseek, |
---|
1213 | | - .release = seq_release, |
---|
| 1231 | +static const struct proc_ops input_devices_proc_ops = { |
---|
| 1232 | + .proc_open = input_proc_devices_open, |
---|
| 1233 | + .proc_poll = input_proc_devices_poll, |
---|
| 1234 | + .proc_read = seq_read, |
---|
| 1235 | + .proc_lseek = seq_lseek, |
---|
| 1236 | + .proc_release = seq_release, |
---|
1214 | 1237 | }; |
---|
1215 | 1238 | |
---|
1216 | 1239 | static void *input_handlers_seq_start(struct seq_file *seq, loff_t *pos) |
---|
.. | .. |
---|
1268 | 1291 | return seq_open(file, &input_handlers_seq_ops); |
---|
1269 | 1292 | } |
---|
1270 | 1293 | |
---|
1271 | | -static const struct file_operations input_handlers_fileops = { |
---|
1272 | | - .owner = THIS_MODULE, |
---|
1273 | | - .open = input_proc_handlers_open, |
---|
1274 | | - .read = seq_read, |
---|
1275 | | - .llseek = seq_lseek, |
---|
1276 | | - .release = seq_release, |
---|
| 1294 | +static const struct proc_ops input_handlers_proc_ops = { |
---|
| 1295 | + .proc_open = input_proc_handlers_open, |
---|
| 1296 | + .proc_read = seq_read, |
---|
| 1297 | + .proc_lseek = seq_lseek, |
---|
| 1298 | + .proc_release = seq_release, |
---|
1277 | 1299 | }; |
---|
1278 | 1300 | |
---|
1279 | 1301 | static int __init input_proc_init(void) |
---|
.. | .. |
---|
1285 | 1307 | return -ENOMEM; |
---|
1286 | 1308 | |
---|
1287 | 1309 | entry = proc_create("devices", 0, proc_bus_input_dir, |
---|
1288 | | - &input_devices_fileops); |
---|
| 1310 | + &input_devices_proc_ops); |
---|
1289 | 1311 | if (!entry) |
---|
1290 | 1312 | goto fail1; |
---|
1291 | 1313 | |
---|
1292 | 1314 | entry = proc_create("handlers", 0, proc_bus_input_dir, |
---|
1293 | | - &input_handlers_fileops); |
---|
| 1315 | + &input_handlers_proc_ops); |
---|
1294 | 1316 | if (!entry) |
---|
1295 | 1317 | goto fail2; |
---|
1296 | 1318 | |
---|
.. | .. |
---|
1520 | 1542 | &input_dev_attr_group, |
---|
1521 | 1543 | &input_dev_id_attr_group, |
---|
1522 | 1544 | &input_dev_caps_attr_group, |
---|
| 1545 | + &input_poller_attribute_group, |
---|
1523 | 1546 | NULL |
---|
1524 | 1547 | }; |
---|
1525 | 1548 | |
---|
.. | .. |
---|
1529 | 1552 | |
---|
1530 | 1553 | input_ff_destroy(dev); |
---|
1531 | 1554 | input_mt_destroy_slots(dev); |
---|
| 1555 | + kfree(dev->poller); |
---|
1532 | 1556 | kfree(dev->absinfo); |
---|
1533 | 1557 | kfree(dev->vals); |
---|
1534 | 1558 | kfree(dev); |
---|
.. | .. |
---|
1963 | 1987 | */ |
---|
1964 | 1988 | void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code) |
---|
1965 | 1989 | { |
---|
| 1990 | + if (type < EV_CNT && input_max_code[type] && |
---|
| 1991 | + code > input_max_code[type]) { |
---|
| 1992 | + pr_err("%s: invalid code %u for type %u\n", __func__, code, |
---|
| 1993 | + type); |
---|
| 1994 | + dump_stack(); |
---|
| 1995 | + return; |
---|
| 1996 | + } |
---|
| 1997 | + |
---|
1966 | 1998 | switch (type) { |
---|
1967 | 1999 | case EV_KEY: |
---|
1968 | 2000 | __set_bit(code, dev->keybit); |
---|
.. | .. |
---|
2193 | 2225 | if (!dev->setkeycode) |
---|
2194 | 2226 | dev->setkeycode = input_default_setkeycode; |
---|
2195 | 2227 | |
---|
| 2228 | + if (dev->poller) |
---|
| 2229 | + input_dev_poller_finalize(dev->poller); |
---|
| 2230 | + |
---|
2196 | 2231 | error = device_add(&dev->dev); |
---|
2197 | 2232 | if (error) |
---|
2198 | 2233 | goto err_free_vals; |
---|