summaryrefslogtreecommitdiff
path: root/drivers/input
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2024-10-23 11:45:24 -0700
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2024-11-05 14:19:47 -0800
commit57a063632df8db6cb20d64ee52a06d4e2049235a (patch)
treeae74cbeb02110a4a884b83f6b1b90b95e283ec4b /drivers/input
parent6b6b40ff05ab43b603abd7ae1821892307421d49 (diff)
downloadlinux-57a063632df8db6cb20d64ee52a06d4e2049235a.tar.gz
linux-57a063632df8db6cb20d64ee52a06d4e2049235a.tar.bz2
linux-57a063632df8db6cb20d64ee52a06d4e2049235a.zip
Input: introduce notion of passive observers for input handlers
Sometimes it is useful to observe (and maybe modify) data coming from an input device, but only do that if there are other users of such input device. An example is touchpad switching functionality on Lenovo IdeaPad Z570 where it is desirable to suppress events coming from the touchpad if user toggles touchpad on/off button (on this laptop the firmware does not stop the device). Introduce notion of passive observers for input handlers to solve this issue. An input handler marked as passive observer behaves exactly like any other input handler or filter, but with one exception: it does not open/start underlying input device when attaching to it. Link: https://lore.kernel.org/r/ZxlEROX7bMo5cbZP@google.com Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/input.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 3c321671793f..3b1e88ead97e 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -605,6 +605,9 @@ int input_open_device(struct input_handle *handle)
handle->open++;
+ if (handle->handler->passive_observer)
+ goto out;
+
if (dev->users++ || dev->inhibited) {
/*
* Device is already opened and/or inhibited,
@@ -668,11 +671,13 @@ void input_close_device(struct input_handle *handle)
__input_release_device(handle);
- if (!--dev->users && !dev->inhibited) {
- if (dev->poller)
- input_dev_poller_stop(dev->poller);
- if (dev->close)
- dev->close(dev);
+ if (!handle->handler->passive_observer) {
+ if (!--dev->users && !dev->inhibited) {
+ if (dev->poller)
+ input_dev_poller_stop(dev->poller);
+ if (dev->close)
+ dev->close(dev);
+ }
}
if (!--handle->open) {