Separating "normal" and "polled" input devices was a mistake, as often we want to allow the very same device work on both interrupt-driven and polled mode, depending on the board on which the device is used. This introduces new APIs: - input_setup_polling - input_set_poll_interval - input_set_min_poll_interval - input_set_max_poll_interval These new APIs allow switching an input device into polled mode with sysfs attributes matching drivers using input_polled_dev APIs that will be eventually removed.
Unified · Split
| @@ -6,7 +6,7 @@ · 5 unmodified lines | |||
| 6 | # Each configuration option enables a list of files. | 6 | # Each configuration option enables a list of files. |
| 7 | 7 | ||
| 8 | obj-$(CONFIG_INPUT) += input-core.o | 8 | obj-$(CONFIG_INPUT) += input-core.o |
| 9 | input-core-y := input.o input-compat.o input-mt.o ff-core.o | 9 | input-core-y := input.o input-compat.o input-mt.o input-poller.o ff-core.o |
| 10 | 10 | ||
| 11 | obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o | 11 | obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o |
| 12 | obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o | 12 | obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o |
| @@ -0,0 +1,213 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | /* | ||
| 3 | * Support for polling mode for input devices. | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <linux/device.h> | ||
| 7 | #include <linux/input.h> | ||
| 8 | #include <linux/jiffies.h> | ||
| 9 | #include <linux/mutex.h> | ||
| 10 | #include <linux/slab.h> | ||
| 11 | #include <linux/types.h> | ||
| 12 | #include <linux/workqueue.h> | ||
| 13 | #include "input-poller.h" | ||
| 14 | |||
| 15 | struct input_dev_poller { | ||
| 16 | void (*poll)(struct input_dev *dev); | ||
| 17 | |||
| 18 | unsigned int poll_interval; /* msec */ | ||
| 19 | unsigned int poll_interval_max; /* msec */ | ||
| 20 | unsigned int poll_interval_min; /* msec */ | ||
| 21 | |||
| 22 | struct input_dev *input; | ||
| 23 | struct delayed_work work; | ||
| 24 | }; | ||
| 25 | |||
| 26 | static void input_dev_poller_queue_work(struct input_dev_poller *poller) | ||
| 27 | { | ||
| 28 | unsigned long delay; | ||
| 29 | |||
| 30 | delay = msecs_to_jiffies(poller->poll_interval); | ||
| 31 | if (delay >= HZ) | ||
| 32 | delay = round_jiffies_relative(delay); | ||
| 33 | |||
| 34 | queue_delayed_work(system_freezable_wq, &poller->work, delay); | ||
| 35 | } | ||
| 36 | |||
| 37 | static void input_dev_poller_work(struct work_struct *work) | ||
| 38 | { | ||
| 39 | struct input_dev_poller *poller = | ||
| 40 | container_of(work, struct input_dev_poller, work.work); | ||
| 41 | |||
| 42 | poller->poll(poller->input); | ||
| 43 | input_dev_poller_queue_work(poller); | ||
| 44 | } | ||
| 45 | |||
| 46 | void input_dev_poller_finalize(struct input_dev_poller *poller) | ||
| 47 | { | ||
| 48 | if (!poller->poll_interval) | ||
| 49 | poller->poll_interval = 500; | ||
| 50 | if (!poller->poll_interval_max) | ||
| 51 | poller->poll_interval_max = poller->poll_interval; | ||
| 52 | } | ||
| 53 | |||
| 54 | void input_dev_poller_start(struct input_dev_poller *poller) | ||
| 55 | { | ||
| 56 | /* Only start polling if polling is enabled */ | ||
| 57 | if (poller->poll_interval > 0) { | ||
| 58 | poller->poll(poller->input); | ||
| 59 | input_dev_poller_queue_work(poller); | ||
| 60 | } | ||
| 61 | } | ||
| 62 | |||
| 63 | void input_dev_poller_stop(struct input_dev_poller *poller) | ||
| 64 | { | ||
| 65 | cancel_delayed_work_sync(&poller->work); | ||
| 66 | } | ||
| 67 | |||
| 68 | int input_setup_polling(struct input_dev *dev, | ||
| 69 | void (*poll_fn)(struct input_dev *dev)) | ||
| 70 | { | ||
| 71 | struct input_dev_poller *poller; | ||
| 72 | |||
| 73 | poller = kzalloc(sizeof(*poller), GFP_KERNEL); | ||
| 74 | if (!poller) { | ||
| 75 | /* | ||
| 76 | * We want to show message even though kzalloc() may have | ||
| 77 | * printed backtrace as knowing what instance of input | ||
| 78 | * device we were dealing with is helpful. | ||
| 79 | */ | ||
| 80 | dev_err(dev->dev.parent ?: &dev->dev, | ||
| 81 | "%s: unable to allocate poller structure\n", __func__); | ||
| 82 | return -ENOMEM; | ||
| 83 | } | ||
| 84 | |||
| 85 | INIT_DELAYED_WORK(&poller->work, input_dev_poller_work); | ||
| 86 | poller->input = dev; | ||
| 87 | poller->poll = poll_fn; | ||
| 88 | |||
| 89 | dev->poller = poller; | ||
| 90 | return 0; | ||
| 91 | } | ||
| 92 | EXPORT_SYMBOL(input_setup_polling); | ||
| 93 | |||
| 94 | static bool input_dev_ensure_poller(struct input_dev *dev) | ||
| 95 | { | ||
| 96 | if (!dev->poller) { | ||
| 97 | dev_err(dev->dev.parent ?: &dev->dev, | ||
| 98 | "poller structure has not been set up\n"); | ||
| 99 | return false; | ||
| 100 | } | ||
| 101 | |||
| 102 | return true; | ||
| 103 | } | ||
| 104 | |||
| 105 | void input_set_poll_interval(struct input_dev *dev, unsigned int interval) | ||
| 106 | { | ||
| 107 | if (input_dev_ensure_poller(dev)) | ||
| 108 | dev->poller->poll_interval = interval; | ||
| 109 | } | ||
| 110 | EXPORT_SYMBOL(input_set_poll_interval); | ||
| 111 | |||
| 112 | void input_set_min_poll_interval(struct input_dev *dev, unsigned int interval) | ||
| 113 | { | ||
| 114 | if (input_dev_ensure_poller(dev)) | ||
| 115 | dev->poller->poll_interval_min = interval; | ||
| 116 | } | ||
| 117 | EXPORT_SYMBOL(input_set_min_poll_interval); | ||
| 118 | |||
| 119 | void input_set_max_poll_interval(struct input_dev *dev, unsigned int interval) | ||
| 120 | { | ||
| 121 | if (input_dev_ensure_poller(dev)) | ||
| 122 | dev->poller->poll_interval_max = interval; | ||
| 123 | } | ||
| 124 | EXPORT_SYMBOL(input_set_max_poll_interval); | ||
| 125 | |||
| 126 | /* SYSFS interface */ | ||
| 127 | |||
| 128 | static ssize_t input_dev_get_poll_interval(struct device *dev, | ||
| 129 | struct device_attribute *attr, | ||
| 130 | char *buf) | ||
| 131 | { | ||
| 132 | struct input_dev *input = to_input_dev(dev); | ||
| 133 | |||
| 134 | return sprintf(buf, "%d\n", input->poller->poll_interval); | ||
| 135 | } | ||
| 136 | |||
| 137 | static ssize_t input_dev_set_poll_interval(struct device *dev, | ||
| 138 | struct device_attribute *attr, | ||
| 139 | const char *buf, size_t count) | ||
| 140 | { | ||
| 141 | struct input_dev *input = to_input_dev(dev); | ||
| 142 | struct input_dev_poller *poller = input->poller; | ||
| 143 | unsigned int interval; | ||
| 144 | int err; | ||
| 145 | |||
| 146 | err = kstrtouint(buf, 0, &interval); | ||
| 147 | if (err) | ||
| 148 | return err; | ||
| 149 | |||
| 150 | if (interval < poller->poll_interval_min) | ||
| 151 | return -EINVAL; | ||
| 152 | |||
| 153 | if (interval > poller->poll_interval_max) | ||
| 154 | return -EINVAL; | ||
| 155 | |||
| 156 | mutex_lock(&input->mutex); | ||
| 157 | |||
| 158 | poller->poll_interval = interval; | ||
| 159 | |||
| 160 | if (input->users) { | ||
| 161 | cancel_delayed_work_sync(&poller->work); | ||
| 162 | if (poller->poll_interval > 0) | ||
| 163 | input_dev_poller_queue_work(poller); | ||
| 164 | } | ||
| 165 | |||
| 166 | mutex_unlock(&input->mutex); | ||
| 167 | |||
| 168 | return count; | ||
| 169 | } | ||
| 170 | |||
| 171 | static DEVICE_ATTR(poll, 0644, | ||
| 172 | input_dev_get_poll_interval, input_dev_set_poll_interval); | ||
| 173 | |||
| 174 | static ssize_t input_dev_get_poll_max(struct device *dev, | ||
| 175 | struct device_attribute *attr, char *buf) | ||
| 176 | { | ||
| 177 | struct input_dev *input = to_input_dev(dev); | ||
| 178 | |||
| 179 | return sprintf(buf, "%d\n", input->poller->poll_interval_max); | ||
| 180 | } | ||
| 181 | |||
| 182 | static DEVICE_ATTR(max, 0444, input_dev_get_poll_max, NULL); | ||
| 183 | |||
| 184 | static ssize_t input_dev_get_poll_min(struct device *dev, | ||
| 185 | struct device_attribute *attr, char *buf) | ||
| 186 | { | ||
| 187 | struct input_dev *input = to_input_dev(dev); | ||
| 188 | |||
| 189 | return sprintf(buf, "%d\n", input->poller->poll_interval_min); | ||
| 190 | } | ||
| 191 | |||
| 192 | static DEVICE_ATTR(min, 0444, input_dev_get_poll_min, NULL); | ||
| 193 | |||
| 194 | static umode_t input_poller_attrs_visible(struct kobject *kobj, | ||
| 195 | struct attribute *attr, int n) | ||
| 196 | { | ||
| 197 | struct device *dev = kobj_to_dev(kobj); | ||
| 198 | struct input_dev *input = to_input_dev(dev); | ||
| 199 | |||
| 200 | return input->poller ? attr->mode : 0; | ||
| 201 | } | ||
| 202 | |||
| 203 | static struct attribute *input_poller_attrs[] = { | ||
| 204 | &dev_attr_poll.attr, | ||
| 205 | &dev_attr_max.attr, | ||
| 206 | &dev_attr_min.attr, | ||
| 207 | NULL | ||
| 208 | }; | ||
| 209 | |||
| 210 | struct attribute_group input_poller_attribute_group = { | ||
| 211 | .is_visible = input_poller_attrs_visible, | ||
| 212 | .attrs = input_poller_attrs, | ||
| 213 | }; | ||
| @@ -0,0 +1,18 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
| 2 | #ifndef _INPUT_POLLER_H | ||
| 3 | #define _INPUT_POLLER_H | ||
| 4 | |||
| 5 | /* | ||
| 6 | * Support for polling mode for input devices. | ||
| 7 | */ | ||
| 8 | #include <linux/sysfs.h> | ||
| 9 | |||
| 10 | struct input_dev_poller; | ||
| 11 | |||
| 12 | void input_dev_poller_finalize(struct input_dev_poller *poller); | ||
| 13 | void input_dev_poller_start(struct input_dev_poller *poller); | ||
| 14 | void input_dev_poller_stop(struct input_dev_poller *poller); | ||
| 15 | |||
| 16 | extern struct attribute_group input_poller_attribute_group; | ||
| 17 | |||
| 18 | #endif /* _INPUT_POLLER_H */ | ||
| @@ -24,6 +24,7 @@ · 23 unmodified lines | |||
| 24 | #include <linux/mutex.h> | 24 | #include <linux/mutex.h> |
| 25 | #include <linux/rcupdate.h> | 25 | #include <linux/rcupdate.h> |
| 26 | #include "input-compat.h" | 26 | #include "input-compat.h" |
| 27 | #include "input-poller.h" | ||
| 27 | 28 | ||
| 28 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); | 29 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); |
| 29 | MODULE_DESCRIPTION("Input core"); | 30 | MODULE_DESCRIPTION("Input core"); |
| @@ -603,20 +604,31 @@ int input_open_device(struct input_handle *handle) · 573 unmodified lines | |||
| 603 | 604 | ||
| 604 | handle->open++; | 605 | handle->open++; |
| 605 | 606 | ||
| 606 | if (!dev->users++ && dev->open) | 607 | if (dev->users++) { |
| 607 | retval = dev->open(dev); | 608 | /* |
| 609 | * Device is already opened, so we can exit immediately and | ||
| 610 | * report success. | ||
| 611 | */ | ||
| 612 | goto out; | ||
| 613 | } | ||
| 608 | 614 | ||
| 609 | if (retval) { | 615 | if (dev->open) { |
| 610 | dev->users--; | 616 | retval = dev->open(dev); |
| 611 | if (!--handle->open) { | 617 | if (retval) { |
| 618 | dev->users--; | ||
| 619 | handle->open--; | ||
| 612 | /* | 620 | /* |
| 613 | * Make sure we are not delivering any more events | 621 | * Make sure we are not delivering any more events |
| 614 | * through this handle | 622 | * through this handle |
| 615 | */ | 623 | */ |
| 616 | synchronize_rcu(); | 624 | synchronize_rcu(); |
| 625 | goto out; | ||
| 617 | } | 626 | } |
| 618 | } | 627 | } |
| 619 | 628 | ||
| 629 | if (dev->poller) | ||
| 630 | input_dev_poller_start(dev->poller); | ||
| 631 | |||
| 620 | out: | 632 | out: |
| 621 | mutex_unlock(&dev->mutex); | 633 | mutex_unlock(&dev->mutex); |
| 622 | return retval; | 634 | return retval; |
| @@ -655,8 +667,13 @@ void input_close_device(struct input_handle *handle) · 32 unmodified lines | |||
| 655 | 667 | ||
| 656 | __input_release_device(handle); | 668 | __input_release_device(handle); |
| 657 | 669 | ||
| 658 | if (!--dev->users && dev->close) | 670 | if (!--dev->users) { |
| 659 | dev->close(dev); | 671 | if (dev->poller) |
| 672 | input_dev_poller_stop(dev->poller); | ||
| 673 | |||
| 674 | if (dev->close) | ||
| 675 | dev->close(dev); | ||
| 676 | } | ||
| 660 | 677 | ||
| 661 | if (!--handle->open) { | 678 | if (!--handle->open) { |
| 662 | /* | 679 | /* |
| @@ -1502,6 +1519,7 @@ static const struct attribute_group *input_dev_attr_groups[] = { · 839 unmodified lines | |||
| 1502 | &input_dev_attr_group, | 1519 | &input_dev_attr_group, |
| 1503 | &input_dev_id_attr_group, | 1520 | &input_dev_id_attr_group, |
| 1504 | &input_dev_caps_attr_group, | 1521 | &input_dev_caps_attr_group, |
| 1522 | &input_poller_attribute_group, | ||
| 1505 | NULL | 1523 | NULL |
| 1506 | }; | 1524 | }; |
| 1507 | 1525 | ||
| @@ -1511,6 +1529,7 @@ static void input_dev_release(struct device *device) · 3 unmodified lines | |||
| 1511 | 1529 | ||
| 1512 | input_ff_destroy(dev); | 1530 | input_ff_destroy(dev); |
| 1513 | input_mt_destroy_slots(dev); | 1531 | input_mt_destroy_slots(dev); |
| 1532 | kfree(dev->poller); | ||
| 1514 | kfree(dev->absinfo); | 1533 | kfree(dev->absinfo); |
| 1515 | kfree(dev->vals); | 1534 | kfree(dev->vals); |
| 1516 | kfree(dev); | 1535 | kfree(dev); |
| @@ -2175,6 +2194,9 @@ int input_register_device(struct input_dev *dev) · 658 unmodified lines | |||
| 2175 | if (!dev->setkeycode) | 2194 | if (!dev->setkeycode) |
| 2176 | dev->setkeycode = input_default_setkeycode; | 2195 | dev->setkeycode = input_default_setkeycode; |
| 2177 | 2196 | ||
| 2197 | if (dev->poller) | ||
| 2198 | input_dev_poller_finalize(dev->poller); | ||
| 2199 | |||
| 2178 | error = device_add(&dev->dev); | 2200 | error = device_add(&dev->dev); |
| 2179 | if (error) | 2201 | if (error) |
| 2180 | goto err_free_vals; | 2202 | goto err_free_vals; |
| @@ -21,6 +21,8 @@ · 20 unmodified lines | |||
| 21 | #include <linux/timer.h> | 21 | #include <linux/timer.h> |
| 22 | #include <linux/mod_devicetable.h> | 22 | #include <linux/mod_devicetable.h> |
| 23 | 23 | ||
| 24 | struct input_dev_poller; | ||
| 25 | |||
| 24 | /** | 26 | /** |
| 25 | * struct input_value - input value representation | 27 | * struct input_value - input value representation |
| 26 | * @type: type of value (EV_KEY, EV_ABS, etc) | 28 | * @type: type of value (EV_KEY, EV_ABS, etc) |
| @@ -71,6 +73,8 @@ enum input_clock_type { · 44 unmodified lines | |||
| 71 | * not sleep | 73 | * not sleep |
| 72 | * @ff: force feedback structure associated with the device if device | 74 | * @ff: force feedback structure associated with the device if device |
| 73 | * supports force feedback effects | 75 | * supports force feedback effects |
| 76 | * @poller: poller structure associated with the device if device is | ||
| 77 | * set up to use polling mode | ||
| 74 | * @repeat_key: stores key code of the last key pressed; used to implement | 78 | * @repeat_key: stores key code of the last key pressed; used to implement |
| 75 | * software autorepeat | 79 | * software autorepeat |
| 76 | * @timer: timer for software autorepeat | 80 | * @timer: timer for software autorepeat |
| @@ -156,6 +160,8 @@ struct input_dev { · 79 unmodified lines | |||
| 156 | 160 | ||
| 157 | struct ff_device *ff; | 161 | struct ff_device *ff; |
| 158 | 162 | ||
| 163 | struct input_dev_poller *poller; | ||
| 164 | |||
| 159 | unsigned int repeat_key; | 165 | unsigned int repeat_key; |
| 160 | struct timer_list timer; | 166 | struct timer_list timer; |
| 161 | 167 | ||
| @@ -372,6 +378,12 @@ void input_unregister_device(struct input_dev *); · 210 unmodified lines | |||
| 372 | 378 | ||
| 373 | void input_reset_device(struct input_dev *); | 379 | void input_reset_device(struct input_dev *); |
| 374 | 380 | ||
| 381 | int input_setup_polling(struct input_dev *dev, | ||
| 382 | void (*poll_fn)(struct input_dev *dev)); | ||
| 383 | void input_set_poll_interval(struct input_dev *dev, unsigned int interval); | ||
| 384 | void input_set_min_poll_interval(struct input_dev *dev, unsigned int interval); | ||
| 385 | void input_set_max_poll_interval(struct input_dev *dev, unsigned int interval); | ||
| 386 | |||
| 375 | int __must_check input_register_handler(struct input_handler *); | 387 | int __must_check input_register_handler(struct input_handler *); |
| 376 | void input_unregister_handler(struct input_handler *); | 388 | void input_unregister_handler(struct input_handler *); |
| 377 | 389 | ||