Merge tag 'input-for-v6.12-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

Pull input fixes from Dmitry Torokhov:

 - a fix for regression in input core introduced in 6.11 preventing
   re-registering input handlers

 - a fix for adp5588-keys driver tyring to disable interrupt 0 at
   suspend when devices is used without interrupt

 - a fix for edt-ft5x06 to stop leaking regmap structure when probing
   fails and to make sure it is not released too early on removal.

* tag 'input-for-v6.12-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  Input: fix regression when re-registering input handlers
  Input: adp5588-keys - do not try to disable interrupt 0
  Input: edt-ft5x06 - fix regmap leak when probe fails
This commit is contained in:
Linus Torvalds
2024-11-03 08:35:29 -10:00
4 changed files with 104 additions and 65 deletions

View File

@@ -119,12 +119,12 @@ static void input_pass_values(struct input_dev *dev,
handle = rcu_dereference(dev->grab);
if (handle) {
count = handle->handler->events(handle, vals, count);
count = handle->handle_events(handle, vals, count);
} else {
list_for_each_entry_rcu(handle, &dev->h_list, d_node)
if (handle->open) {
count = handle->handler->events(handle, vals,
count);
count = handle->handle_events(handle, vals,
count);
if (!count)
break;
}
@@ -2534,57 +2534,6 @@ static int input_handler_check_methods(const struct input_handler *handler)
return 0;
}
/*
* An implementation of input_handler's events() method that simply
* invokes handler->event() method for each event one by one.
*/
static unsigned int input_handler_events_default(struct input_handle *handle,
struct input_value *vals,
unsigned int count)
{
struct input_handler *handler = handle->handler;
struct input_value *v;
for (v = vals; v != vals + count; v++)
handler->event(handle, v->type, v->code, v->value);
return count;
}
/*
* An implementation of input_handler's events() method that invokes
* handler->filter() method for each event one by one and removes events
* that were filtered out from the "vals" array.
*/
static unsigned int input_handler_events_filter(struct input_handle *handle,
struct input_value *vals,
unsigned int count)
{
struct input_handler *handler = handle->handler;
struct input_value *end = vals;
struct input_value *v;
for (v = vals; v != vals + count; v++) {
if (handler->filter(handle, v->type, v->code, v->value))
continue;
if (end != v)
*end = *v;
end++;
}
return end - vals;
}
/*
* An implementation of input_handler's events() method that does nothing.
*/
static unsigned int input_handler_events_null(struct input_handle *handle,
struct input_value *vals,
unsigned int count)
{
return count;
}
/**
* input_register_handler - register a new input handler
* @handler: handler to be registered
@@ -2604,13 +2553,6 @@ int input_register_handler(struct input_handler *handler)
INIT_LIST_HEAD(&handler->h_list);
if (handler->filter)
handler->events = input_handler_events_filter;
else if (handler->event)
handler->events = input_handler_events_default;
else if (!handler->events)
handler->events = input_handler_events_null;
error = mutex_lock_interruptible(&input_mutex);
if (error)
return error;
@@ -2684,6 +2626,75 @@ int input_handler_for_each_handle(struct input_handler *handler, void *data,
}
EXPORT_SYMBOL(input_handler_for_each_handle);
/*
* An implementation of input_handle's handle_events() method that simply
* invokes handler->event() method for each event one by one.
*/
static unsigned int input_handle_events_default(struct input_handle *handle,
struct input_value *vals,
unsigned int count)
{
struct input_handler *handler = handle->handler;
struct input_value *v;
for (v = vals; v != vals + count; v++)
handler->event(handle, v->type, v->code, v->value);
return count;
}
/*
* An implementation of input_handle's handle_events() method that invokes
* handler->filter() method for each event one by one and removes events
* that were filtered out from the "vals" array.
*/
static unsigned int input_handle_events_filter(struct input_handle *handle,
struct input_value *vals,
unsigned int count)
{
struct input_handler *handler = handle->handler;
struct input_value *end = vals;
struct input_value *v;
for (v = vals; v != vals + count; v++) {
if (handler->filter(handle, v->type, v->code, v->value))
continue;
if (end != v)
*end = *v;
end++;
}
return end - vals;
}
/*
* An implementation of input_handle's handle_events() method that does nothing.
*/
static unsigned int input_handle_events_null(struct input_handle *handle,
struct input_value *vals,
unsigned int count)
{
return count;
}
/*
* Sets up appropriate handle->event_handler based on the input_handler
* associated with the handle.
*/
static void input_handle_setup_event_handler(struct input_handle *handle)
{
struct input_handler *handler = handle->handler;
if (handler->filter)
handle->handle_events = input_handle_events_filter;
else if (handler->event)
handle->handle_events = input_handle_events_default;
else if (handler->events)
handle->handle_events = handler->events;
else
handle->handle_events = input_handle_events_null;
}
/**
* input_register_handle - register a new input handle
* @handle: handle to register
@@ -2701,6 +2712,7 @@ int input_register_handle(struct input_handle *handle)
struct input_dev *dev = handle->dev;
int error;
input_handle_setup_event_handler(handle);
/*
* We take dev->mutex here to prevent race with
* input_release_device().