Skip to content

Commit 295ba65

Browse files
committed
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
2 parents a33ab3f + 071b24b commit 295ba65

File tree

4 files changed

+104
-65
lines changed

4 files changed

+104
-65
lines changed

drivers/input/input.c

Lines changed: 73 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,12 @@ static void input_pass_values(struct input_dev *dev,
119119

120120
handle = rcu_dereference(dev->grab);
121121
if (handle) {
122-
count = handle->handler->events(handle, vals, count);
122+
count = handle->handle_events(handle, vals, count);
123123
} else {
124124
list_for_each_entry_rcu(handle, &dev->h_list, d_node)
125125
if (handle->open) {
126-
count = handle->handler->events(handle, vals,
127-
count);
126+
count = handle->handle_events(handle, vals,
127+
count);
128128
if (!count)
129129
break;
130130
}
@@ -2534,57 +2534,6 @@ static int input_handler_check_methods(const struct input_handler *handler)
25342534
return 0;
25352535
}
25362536

2537-
/*
2538-
* An implementation of input_handler's events() method that simply
2539-
* invokes handler->event() method for each event one by one.
2540-
*/
2541-
static unsigned int input_handler_events_default(struct input_handle *handle,
2542-
struct input_value *vals,
2543-
unsigned int count)
2544-
{
2545-
struct input_handler *handler = handle->handler;
2546-
struct input_value *v;
2547-
2548-
for (v = vals; v != vals + count; v++)
2549-
handler->event(handle, v->type, v->code, v->value);
2550-
2551-
return count;
2552-
}
2553-
2554-
/*
2555-
* An implementation of input_handler's events() method that invokes
2556-
* handler->filter() method for each event one by one and removes events
2557-
* that were filtered out from the "vals" array.
2558-
*/
2559-
static unsigned int input_handler_events_filter(struct input_handle *handle,
2560-
struct input_value *vals,
2561-
unsigned int count)
2562-
{
2563-
struct input_handler *handler = handle->handler;
2564-
struct input_value *end = vals;
2565-
struct input_value *v;
2566-
2567-
for (v = vals; v != vals + count; v++) {
2568-
if (handler->filter(handle, v->type, v->code, v->value))
2569-
continue;
2570-
if (end != v)
2571-
*end = *v;
2572-
end++;
2573-
}
2574-
2575-
return end - vals;
2576-
}
2577-
2578-
/*
2579-
* An implementation of input_handler's events() method that does nothing.
2580-
*/
2581-
static unsigned int input_handler_events_null(struct input_handle *handle,
2582-
struct input_value *vals,
2583-
unsigned int count)
2584-
{
2585-
return count;
2586-
}
2587-
25882537
/**
25892538
* input_register_handler - register a new input handler
25902539
* @handler: handler to be registered
@@ -2604,13 +2553,6 @@ int input_register_handler(struct input_handler *handler)
26042553

26052554
INIT_LIST_HEAD(&handler->h_list);
26062555

2607-
if (handler->filter)
2608-
handler->events = input_handler_events_filter;
2609-
else if (handler->event)
2610-
handler->events = input_handler_events_default;
2611-
else if (!handler->events)
2612-
handler->events = input_handler_events_null;
2613-
26142556
error = mutex_lock_interruptible(&input_mutex);
26152557
if (error)
26162558
return error;
@@ -2684,6 +2626,75 @@ int input_handler_for_each_handle(struct input_handler *handler, void *data,
26842626
}
26852627
EXPORT_SYMBOL(input_handler_for_each_handle);
26862628

2629+
/*
2630+
* An implementation of input_handle's handle_events() method that simply
2631+
* invokes handler->event() method for each event one by one.
2632+
*/
2633+
static unsigned int input_handle_events_default(struct input_handle *handle,
2634+
struct input_value *vals,
2635+
unsigned int count)
2636+
{
2637+
struct input_handler *handler = handle->handler;
2638+
struct input_value *v;
2639+
2640+
for (v = vals; v != vals + count; v++)
2641+
handler->event(handle, v->type, v->code, v->value);
2642+
2643+
return count;
2644+
}
2645+
2646+
/*
2647+
* An implementation of input_handle's handle_events() method that invokes
2648+
* handler->filter() method for each event one by one and removes events
2649+
* that were filtered out from the "vals" array.
2650+
*/
2651+
static unsigned int input_handle_events_filter(struct input_handle *handle,
2652+
struct input_value *vals,
2653+
unsigned int count)
2654+
{
2655+
struct input_handler *handler = handle->handler;
2656+
struct input_value *end = vals;
2657+
struct input_value *v;
2658+
2659+
for (v = vals; v != vals + count; v++) {
2660+
if (handler->filter(handle, v->type, v->code, v->value))
2661+
continue;
2662+
if (end != v)
2663+
*end = *v;
2664+
end++;
2665+
}
2666+
2667+
return end - vals;
2668+
}
2669+
2670+
/*
2671+
* An implementation of input_handle's handle_events() method that does nothing.
2672+
*/
2673+
static unsigned int input_handle_events_null(struct input_handle *handle,
2674+
struct input_value *vals,
2675+
unsigned int count)
2676+
{
2677+
return count;
2678+
}
2679+
2680+
/*
2681+
* Sets up appropriate handle->event_handler based on the input_handler
2682+
* associated with the handle.
2683+
*/
2684+
static void input_handle_setup_event_handler(struct input_handle *handle)
2685+
{
2686+
struct input_handler *handler = handle->handler;
2687+
2688+
if (handler->filter)
2689+
handle->handle_events = input_handle_events_filter;
2690+
else if (handler->event)
2691+
handle->handle_events = input_handle_events_default;
2692+
else if (handler->events)
2693+
handle->handle_events = handler->events;
2694+
else
2695+
handle->handle_events = input_handle_events_null;
2696+
}
2697+
26872698
/**
26882699
* input_register_handle - register a new input handle
26892700
* @handle: handle to register
@@ -2701,6 +2712,7 @@ int input_register_handle(struct input_handle *handle)
27012712
struct input_dev *dev = handle->dev;
27022713
int error;
27032714

2715+
input_handle_setup_event_handler(handle);
27042716
/*
27052717
* We take dev->mutex here to prevent race with
27062718
* input_release_device().

drivers/input/keyboard/adp5588-keys.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,8 @@ static int adp5588_suspend(struct device *dev)
822822
{
823823
struct i2c_client *client = to_i2c_client(dev);
824824

825-
disable_irq(client->irq);
825+
if (client->irq)
826+
disable_irq(client->irq);
826827

827828
return 0;
828829
}
@@ -831,7 +832,8 @@ static int adp5588_resume(struct device *dev)
831832
{
832833
struct i2c_client *client = to_i2c_client(dev);
833834

834-
enable_irq(client->irq);
835+
if (client->irq)
836+
enable_irq(client->irq);
835837

836838
return 0;
837839
}

drivers/input/touchscreen/edt-ft5x06.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1121,6 +1121,14 @@ static void edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata)
11211121
}
11221122
}
11231123

1124+
static void edt_ft5x06_exit_regmap(void *arg)
1125+
{
1126+
struct edt_ft5x06_ts_data *data = arg;
1127+
1128+
if (!IS_ERR_OR_NULL(data->regmap))
1129+
regmap_exit(data->regmap);
1130+
}
1131+
11241132
static void edt_ft5x06_disable_regulators(void *arg)
11251133
{
11261134
struct edt_ft5x06_ts_data *data = arg;
@@ -1154,6 +1162,16 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client)
11541162
return PTR_ERR(tsdata->regmap);
11551163
}
11561164

1165+
/*
1166+
* We are not using devm_regmap_init_i2c() and instead install a
1167+
* custom action because we may replace regmap with M06-specific one
1168+
* and we need to make sure that it will not be released too early.
1169+
*/
1170+
error = devm_add_action_or_reset(&client->dev, edt_ft5x06_exit_regmap,
1171+
tsdata);
1172+
if (error)
1173+
return error;
1174+
11571175
chip_data = device_get_match_data(&client->dev);
11581176
if (!chip_data)
11591177
chip_data = (const struct edt_i2c_chip_data *)id->driver_data;
@@ -1347,7 +1365,6 @@ static void edt_ft5x06_ts_remove(struct i2c_client *client)
13471365
struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
13481366

13491367
edt_ft5x06_ts_teardown_debugfs(tsdata);
1350-
regmap_exit(tsdata->regmap);
13511368
}
13521369

13531370
static int edt_ft5x06_ts_suspend(struct device *dev)

include/linux/input.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,12 +339,16 @@ struct input_handler {
339339
* @name: name given to the handle by handler that created it
340340
* @dev: input device the handle is attached to
341341
* @handler: handler that works with the device through this handle
342+
* @handle_events: event sequence handler. It is set up by the input core
343+
* according to event handling method specified in the @handler. See
344+
* input_handle_setup_event_handler().
345+
* This method is being called by the input core with interrupts disabled
346+
* and dev->event_lock spinlock held and so it may not sleep.
342347
* @d_node: used to put the handle on device's list of attached handles
343348
* @h_node: used to put the handle on handler's list of handles from which
344349
* it gets events
345350
*/
346351
struct input_handle {
347-
348352
void *private;
349353

350354
int open;
@@ -353,6 +357,10 @@ struct input_handle {
353357
struct input_dev *dev;
354358
struct input_handler *handler;
355359

360+
unsigned int (*handle_events)(struct input_handle *handle,
361+
struct input_value *vals,
362+
unsigned int count);
363+
356364
struct list_head d_node;
357365
struct list_head h_node;
358366
};

0 commit comments

Comments
 (0)