aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/input/input.c41
-rw-r--r--include/linux/input.h8
2 files changed, 42 insertions, 7 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 6c161e220868..7080a9d4b840 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -86,12 +86,14 @@ static int input_defuzz_abs_event(int value, int old_val, int fuzz)
86} 86}
87 87
88/* 88/*
89 * Pass event through all open handles. This function is called with 89 * Pass event first through all filters and then, if event has not been
90 * filtered out, through all open handles. This function is called with
90 * dev->event_lock held and interrupts disabled. 91 * dev->event_lock held and interrupts disabled.
91 */ 92 */
92static void input_pass_event(struct input_dev *dev, 93static void input_pass_event(struct input_dev *dev,
93 unsigned int type, unsigned int code, int value) 94 unsigned int type, unsigned int code, int value)
94{ 95{
96 struct input_handler *handler;
95 struct input_handle *handle; 97 struct input_handle *handle;
96 98
97 rcu_read_lock(); 99 rcu_read_lock();
@@ -99,11 +101,25 @@ static void input_pass_event(struct input_dev *dev,
99 handle = rcu_dereference(dev->grab); 101 handle = rcu_dereference(dev->grab);
100 if (handle) 102 if (handle)
101 handle->handler->event(handle, type, code, value); 103 handle->handler->event(handle, type, code, value);
102 else 104 else {
103 list_for_each_entry_rcu(handle, &dev->h_list, d_node) 105 bool filtered = false;
104 if (handle->open) 106
105 handle->handler->event(handle, 107 list_for_each_entry_rcu(handle, &dev->h_list, d_node) {
106 type, code, value); 108 if (!handle->open)
109 continue;
110
111 handler = handle->handler;
112 if (!handler->filter) {
113 if (filtered)
114 break;
115
116 handler->event(handle, type, code, value);
117
118 } else if (handler->filter(handle, type, code, value))
119 filtered = true;
120 }
121 }
122
107 rcu_read_unlock(); 123 rcu_read_unlock();
108} 124}
109 125
@@ -990,6 +1006,8 @@ static int input_handlers_seq_show(struct seq_file *seq, void *v)
990 union input_seq_state *state = (union input_seq_state *)&seq->private; 1006 union input_seq_state *state = (union input_seq_state *)&seq->private;
991 1007
992 seq_printf(seq, "N: Number=%u Name=%s", state->pos, handler->name); 1008 seq_printf(seq, "N: Number=%u Name=%s", state->pos, handler->name);
1009 if (handler->filter)
1010 seq_puts(seq, " (filter)");
993 if (handler->fops) 1011 if (handler->fops)
994 seq_printf(seq, " Minor=%d", handler->minor); 1012 seq_printf(seq, " Minor=%d", handler->minor);
995 seq_putc(seq, '\n'); 1013 seq_putc(seq, '\n');
@@ -1803,7 +1821,16 @@ int input_register_handle(struct input_handle *handle)
1803 error = mutex_lock_interruptible(&dev->mutex); 1821 error = mutex_lock_interruptible(&dev->mutex);
1804 if (error) 1822 if (error)
1805 return error; 1823 return error;
1806 list_add_tail_rcu(&handle->d_node, &dev->h_list); 1824
1825 /*
1826 * Filters go to the head of the list, normal handlers
1827 * to the tail.
1828 */
1829 if (handler->filter)
1830 list_add_rcu(&handle->d_node, &dev->h_list);
1831 else
1832 list_add_tail_rcu(&handle->d_node, &dev->h_list);
1833
1807 mutex_unlock(&dev->mutex); 1834 mutex_unlock(&dev->mutex);
1808 1835
1809 /* 1836 /*
diff --git a/include/linux/input.h b/include/linux/input.h
index 7be8a6537b57..6c9d3d49fa91 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -1198,6 +1198,8 @@ struct input_handle;
1198 * @event: event handler. This method is being called by input core with 1198 * @event: event handler. This method is being called by input core with
1199 * interrupts disabled and dev->event_lock spinlock held and so 1199 * interrupts disabled and dev->event_lock spinlock held and so
1200 * it may not sleep 1200 * it may not sleep
1201 * @filter: similar to @event; separates normal event handlers from
1202 * "filters".
1201 * @connect: called when attaching a handler to an input device 1203 * @connect: called when attaching a handler to an input device
1202 * @disconnect: disconnects a handler from input device 1204 * @disconnect: disconnects a handler from input device
1203 * @start: starts handler for given handle. This function is called by 1205 * @start: starts handler for given handle. This function is called by
@@ -1219,6 +1221,11 @@ struct input_handle;
1219 * same time. All of them will get their copy of input event generated by 1221 * same time. All of them will get their copy of input event generated by
1220 * the device. 1222 * the device.
1221 * 1223 *
1224 * The very same structure is used to implement input filters. Input core
1225 * allows filters to run first and will not pass event to regular handlers
1226 * if any of the filters indicate that the event should be filtered (by
1227 * returning %true from their filter() method).
1228 *
1222 * Note that input core serializes calls to connect() and disconnect() 1229 * Note that input core serializes calls to connect() and disconnect()
1223 * methods. 1230 * methods.
1224 */ 1231 */
@@ -1227,6 +1234,7 @@ struct input_handler {
1227 void *private; 1234 void *private;
1228 1235
1229 void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value); 1236 void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
1237 bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
1230 int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id); 1238 int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);
1231 void (*disconnect)(struct input_handle *handle); 1239 void (*disconnect)(struct input_handle *handle);
1232 void (*start)(struct input_handle *handle); 1240 void (*start)(struct input_handle *handle);