From 78d4f34e2115b517bcbfe7ec0d018bbbb6f9b0b8 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 15 Dec 2024 15:58:23 -0800 Subject: [PATCH 01/16] Linux 6.13-rc3 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 64c594bd7ad0..e5b8a8832c0c 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 6 PATCHLEVEL = 13 SUBLEVEL = 0 -EXTRAVERSION = -rc2 +EXTRAVERSION = -rc3 NAME = Baby Opossum Posse # *DOCUMENTATION* -- 2.51.0 From 828fd3f1d611cff5accb9fbff75f6bb011d8c9e2 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Mon, 16 Dec 2024 09:32:17 +0100 Subject: [PATCH 02/16] Input: davinci-keyscan - remove leftover header The corresponding driver was removed two years ago but the platform data header was left behind. Remove it now. Fixes: 3c9cb34939fb ("input: remove davinci keyboard driver") Signed-off-by: Bartosz Golaszewski Acked-by: Arnd Bergmann Link: https://lore.kernel.org/r/20241216083218.22926-1-brgl@bgdev.pl Signed-off-by: Dmitry Torokhov --- include/linux/platform_data/keyscan-davinci.h | 29 ------------------- 1 file changed, 29 deletions(-) delete mode 100644 include/linux/platform_data/keyscan-davinci.h diff --git a/include/linux/platform_data/keyscan-davinci.h b/include/linux/platform_data/keyscan-davinci.h deleted file mode 100644 index 260d596ba0af..000000000000 --- a/include/linux/platform_data/keyscan-davinci.h +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (C) 2009 Texas Instruments, Inc - * - * Author: Miguel Aguilar - */ - -#ifndef DAVINCI_KEYSCAN_H -#define DAVINCI_KEYSCAN_H - -#include - -enum davinci_matrix_types { - DAVINCI_KEYSCAN_MATRIX_4X4, - DAVINCI_KEYSCAN_MATRIX_5X3, -}; - -struct davinci_ks_platform_data { - int (*device_enable)(struct device *dev); - unsigned short *keymap; - u32 keymapsize; - u8 rep:1; - u8 strobe; - u8 interval; - u8 matrix_type; -}; - -#endif - -- 2.51.0 From e571f988af1b62b701fc85fb74df878acc0a9857 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Tue, 17 Dec 2024 11:47:39 +0100 Subject: [PATCH 03/16] Input: remove evbug driver I've never heard of anyone having used this driver for debugging at least in over past decade or so. Since we have tools like evtest, this driver seems to be rather superficial. Also, it apparently causes confusion among people who accidentaly enable CONFIG_INPUT_EVBUG and are annoyed/confused by their kernel log being spammed by a lot of useless data. Let's just remove it. Signed-off-by: Jiri Kosina Link: https://lore.kernel.org/r/8n377s5p-3r9n-ro38-3r2o-p536745552qo@xreary.bet Signed-off-by: Dmitry Torokhov --- drivers/input/Kconfig | 14 ------ drivers/input/Makefile | 1 - drivers/input/evbug.c | 100 ----------------------------------------- 3 files changed, 115 deletions(-) delete mode 100644 drivers/input/evbug.c diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 3bdbd34314b3..88ecdf5218ee 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -152,20 +152,6 @@ config INPUT_EVDEV To compile this driver as a module, choose M here: the module will be called evdev. -config INPUT_EVBUG - tristate "Event debugging" - help - Say Y here if you have a problem with the input subsystem and - want all events (keypresses, mouse movements), to be output to - the system log. While this is useful for debugging, it's also - a security threat - your keypresses include your passwords, of - course. - - If unsure, say N. - - To compile this driver as a module, choose M here: the - module will be called evbug. - config INPUT_KUNIT_TEST tristate "KUnit tests for Input" if !KUNIT_ALL_TESTS depends on INPUT && KUNIT diff --git a/drivers/input/Makefile b/drivers/input/Makefile index c78753274921..930b64d2115e 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile @@ -18,7 +18,6 @@ obj-$(CONFIG_INPUT_LEDS) += input-leds.o obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o obj-$(CONFIG_INPUT_JOYDEV) += joydev.o obj-$(CONFIG_INPUT_EVDEV) += evdev.o -obj-$(CONFIG_INPUT_EVBUG) += evbug.o obj-$(CONFIG_INPUT_KEYBOARD) += keyboard/ obj-$(CONFIG_INPUT_MOUSE) += mouse/ diff --git a/drivers/input/evbug.c b/drivers/input/evbug.c deleted file mode 100644 index e47bdf92088a..000000000000 --- a/drivers/input/evbug.c +++ /dev/null @@ -1,100 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (c) 1999-2001 Vojtech Pavlik - */ - -/* - * Input driver event debug module - dumps all events into syslog - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include - -MODULE_AUTHOR("Vojtech Pavlik "); -MODULE_DESCRIPTION("Input driver event debug module"); -MODULE_LICENSE("GPL"); - -static void evbug_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) -{ - printk(KERN_DEBUG pr_fmt("Event. Dev: %s, Type: %d, Code: %d, Value: %d\n"), - dev_name(&handle->dev->dev), type, code, value); -} - -static int evbug_connect(struct input_handler *handler, struct input_dev *dev, - const struct input_device_id *id) -{ - struct input_handle *handle; - int error; - - handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); - if (!handle) - return -ENOMEM; - - handle->dev = dev; - handle->handler = handler; - handle->name = "evbug"; - - error = input_register_handle(handle); - if (error) - goto err_free_handle; - - error = input_open_device(handle); - if (error) - goto err_unregister_handle; - - printk(KERN_DEBUG pr_fmt("Connected device: %s (%s at %s)\n"), - dev_name(&dev->dev), - dev->name ?: "unknown", - dev->phys ?: "unknown"); - - return 0; - - err_unregister_handle: - input_unregister_handle(handle); - err_free_handle: - kfree(handle); - return error; -} - -static void evbug_disconnect(struct input_handle *handle) -{ - printk(KERN_DEBUG pr_fmt("Disconnected device: %s\n"), - dev_name(&handle->dev->dev)); - - input_close_device(handle); - input_unregister_handle(handle); - kfree(handle); -} - -static const struct input_device_id evbug_ids[] = { - { .driver_info = 1 }, /* Matches all devices */ - { }, /* Terminating zero entry */ -}; - -MODULE_DEVICE_TABLE(input, evbug_ids); - -static struct input_handler evbug_handler = { - .event = evbug_event, - .connect = evbug_connect, - .disconnect = evbug_disconnect, - .name = "evbug", - .id_table = evbug_ids, -}; - -static int __init evbug_init(void) -{ - return input_register_handler(&evbug_handler); -} - -static void __exit evbug_exit(void) -{ - input_unregister_handler(&evbug_handler); -} - -module_init(evbug_init); -module_exit(evbug_exit); -- 2.51.0 From 3d11c09d41284ca94c752864e570e917c0273d65 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 6 Nov 2024 23:15:28 -0800 Subject: [PATCH 04/16] Input: ff-core - convert locking to guard notation Use guard() and scoped_guard() notation instead of explicitly acquiring and releasing spinlocks and mutexes to simplify the code and ensure that all locks are released properly. Link: https://lore.kernel.org/r/20241107071538.195340-2-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/ff-core.c | 71 +++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 42 deletions(-) diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c index 609a5f01761b..eb01bcb69d00 100644 --- a/drivers/input/ff-core.c +++ b/drivers/input/ff-core.c @@ -93,7 +93,7 @@ int input_ff_upload(struct input_dev *dev, struct ff_effect *effect, { struct ff_device *ff = dev->ff; struct ff_effect *old; - int ret = 0; + int error; int id; if (!test_bit(EV_FF, dev->evbit)) @@ -114,22 +114,20 @@ int input_ff_upload(struct input_dev *dev, struct ff_effect *effect, } if (!test_bit(effect->type, ff->ffbit)) { - ret = compat_effect(ff, effect); - if (ret) - return ret; + error = compat_effect(ff, effect); + if (error) + return error; } - mutex_lock(&ff->mutex); + guard(mutex)(&ff->mutex); if (effect->id == -1) { for (id = 0; id < ff->max_effects; id++) if (!ff->effect_owners[id]) break; - if (id >= ff->max_effects) { - ret = -ENOSPC; - goto out; - } + if (id >= ff->max_effects) + return -ENOSPC; effect->id = id; old = NULL; @@ -137,30 +135,26 @@ int input_ff_upload(struct input_dev *dev, struct ff_effect *effect, } else { id = effect->id; - ret = check_effect_access(ff, id, file); - if (ret) - goto out; + error = check_effect_access(ff, id, file); + if (error) + return error; old = &ff->effects[id]; - if (!check_effects_compatible(effect, old)) { - ret = -EINVAL; - goto out; - } + if (!check_effects_compatible(effect, old)) + return -EINVAL; } - ret = ff->upload(dev, effect, old); - if (ret) - goto out; + error = ff->upload(dev, effect, old); + if (error) + return error; - spin_lock_irq(&dev->event_lock); - ff->effects[id] = *effect; - ff->effect_owners[id] = file; - spin_unlock_irq(&dev->event_lock); + scoped_guard(spinlock_irq, &dev->event_lock) { + ff->effects[id] = *effect; + ff->effect_owners[id] = file; + } - out: - mutex_unlock(&ff->mutex); - return ret; + return 0; } EXPORT_SYMBOL_GPL(input_ff_upload); @@ -178,17 +172,16 @@ static int erase_effect(struct input_dev *dev, int effect_id, if (error) return error; - spin_lock_irq(&dev->event_lock); - ff->playback(dev, effect_id, 0); - ff->effect_owners[effect_id] = NULL; - spin_unlock_irq(&dev->event_lock); + scoped_guard(spinlock_irq, &dev->event_lock) { + ff->playback(dev, effect_id, 0); + ff->effect_owners[effect_id] = NULL; + } if (ff->erase) { error = ff->erase(dev, effect_id); if (error) { - spin_lock_irq(&dev->event_lock); - ff->effect_owners[effect_id] = file; - spin_unlock_irq(&dev->event_lock); + scoped_guard(spinlock_irq, &dev->event_lock) + ff->effect_owners[effect_id] = file; return error; } @@ -210,16 +203,12 @@ static int erase_effect(struct input_dev *dev, int effect_id, int input_ff_erase(struct input_dev *dev, int effect_id, struct file *file) { struct ff_device *ff = dev->ff; - int ret; if (!test_bit(EV_FF, dev->evbit)) return -ENOSYS; - mutex_lock(&ff->mutex); - ret = erase_effect(dev, effect_id, file); - mutex_unlock(&ff->mutex); - - return ret; + guard(mutex)(&ff->mutex); + return erase_effect(dev, effect_id, file); } EXPORT_SYMBOL_GPL(input_ff_erase); @@ -239,13 +228,11 @@ int input_ff_flush(struct input_dev *dev, struct file *file) dev_dbg(&dev->dev, "flushing now\n"); - mutex_lock(&ff->mutex); + guard(mutex)(&ff->mutex); for (i = 0; i < ff->max_effects; i++) erase_effect(dev, i, file); - mutex_unlock(&ff->mutex); - return 0; } EXPORT_SYMBOL_GPL(input_ff_flush); -- 2.51.0 From 19c8d0ef1e93d96a2552893df7468a1ff1cd963f Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 6 Nov 2024 23:15:29 -0800 Subject: [PATCH 05/16] Input: ff-core - make use of __free() cleanup facility Annotate allocated memory with __free(kfree) to simplify the code and make sure memory is released appropriately. Tested-by: Marek Szyprowski Link: https://lore.kernel.org/r/20241107071538.195340-3-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/ff-core.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c index eb01bcb69d00..b527308cb52e 100644 --- a/drivers/input/ff-core.c +++ b/drivers/input/ff-core.c @@ -290,8 +290,6 @@ EXPORT_SYMBOL_GPL(input_ff_event); */ int input_ff_create(struct input_dev *dev, unsigned int max_effects) { - struct ff_device *ff; - size_t ff_dev_size; int i; if (!max_effects) { @@ -304,25 +302,19 @@ int input_ff_create(struct input_dev *dev, unsigned int max_effects) return -EINVAL; } - ff_dev_size = struct_size(ff, effect_owners, max_effects); - if (ff_dev_size == SIZE_MAX) /* overflow */ - return -EINVAL; - - ff = kzalloc(ff_dev_size, GFP_KERNEL); + struct ff_device *ff __free(kfree) = + kzalloc(struct_size(ff, effect_owners, max_effects), + GFP_KERNEL); if (!ff) return -ENOMEM; - ff->effects = kcalloc(max_effects, sizeof(struct ff_effect), - GFP_KERNEL); - if (!ff->effects) { - kfree(ff); + ff->effects = kcalloc(max_effects, sizeof(*ff->effects), GFP_KERNEL); + if (!ff->effects) return -ENOMEM; - } ff->max_effects = max_effects; mutex_init(&ff->mutex); - dev->ff = ff; dev->flush = input_ff_flush; dev->event = input_ff_event; __set_bit(EV_FF, dev->evbit); @@ -335,6 +327,8 @@ int input_ff_create(struct input_dev *dev, unsigned int max_effects) if (test_bit(FF_PERIODIC, ff->ffbit)) __set_bit(FF_RUMBLE, dev->ffbit); + dev->ff = no_free_ptr(ff); + return 0; } EXPORT_SYMBOL_GPL(input_ff_create); -- 2.51.0 From cec6b33a6786e3ecad4b1d4bb7843d122ffa1912 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 6 Nov 2024 23:15:30 -0800 Subject: [PATCH 06/16] Input: ff-memless - convert locking to guard notation Use guard() notation instead of explicitly acquiring and releasing spinlocks to simplify the code and ensure that all locks are released. Link: https://lore.kernel.org/r/20241107071538.195340-4-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/ff-memless.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c index c321cdabd214..ec99c070a97c 100644 --- a/drivers/input/ff-memless.c +++ b/drivers/input/ff-memless.c @@ -401,13 +401,11 @@ static void ml_effect_timer(struct timer_list *t) { struct ml_device *ml = from_timer(ml, t, timer); struct input_dev *dev = ml->dev; - unsigned long flags; pr_debug("timer: updating effects\n"); - spin_lock_irqsave(&dev->event_lock, flags); + guard(spinlock_irqsave)(&dev->event_lock); ml_play_effects(ml); - spin_unlock_irqrestore(&dev->event_lock, flags); } /* @@ -465,7 +463,7 @@ static int ml_ff_upload(struct input_dev *dev, struct ml_device *ml = dev->ff->private; struct ml_effect_state *state = &ml->states[effect->id]; - spin_lock_irq(&dev->event_lock); + guard(spinlock_irq)(&dev->event_lock); if (test_bit(FF_EFFECT_STARTED, &state->flags)) { __clear_bit(FF_EFFECT_PLAYING, &state->flags); @@ -477,8 +475,6 @@ static int ml_ff_upload(struct input_dev *dev, ml_schedule_timer(ml); } - spin_unlock_irq(&dev->event_lock); - return 0; } -- 2.51.0 From 96173d61028736464b305da7bd6b9fb1b8e85d02 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 6 Nov 2024 23:15:31 -0800 Subject: [PATCH 07/16] Input: ff-memless - make use of __free() cleanup facility Annotate allocated memory with __free(kfree) to simplify the code and make sure memory is released appropriately. Tested-by: Marek Szyprowski Link: https://lore.kernel.org/r/20241107071538.195340-5-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/ff-memless.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c index ec99c070a97c..e9120ba6bae0 100644 --- a/drivers/input/ff-memless.c +++ b/drivers/input/ff-memless.c @@ -503,12 +503,11 @@ static void ml_ff_destroy(struct ff_device *ff) int input_ff_create_memless(struct input_dev *dev, void *data, int (*play_effect)(struct input_dev *, void *, struct ff_effect *)) { - struct ml_device *ml; struct ff_device *ff; int error; int i; - ml = kzalloc(sizeof(struct ml_device), GFP_KERNEL); + struct ml_device *ml __free(kfree) = kzalloc(sizeof(*ml), GFP_KERNEL); if (!ml) return -ENOMEM; @@ -521,13 +520,10 @@ int input_ff_create_memless(struct input_dev *dev, void *data, set_bit(FF_GAIN, dev->ffbit); error = input_ff_create(dev, FF_MEMLESS_EFFECTS); - if (error) { - kfree(ml); + if (error) return error; - } ff = dev->ff; - ff->private = ml; ff->upload = ml_ff_upload; ff->playback = ml_ff_playback; ff->set_gain = ml_ff_set_gain; @@ -544,6 +540,8 @@ int input_ff_create_memless(struct input_dev *dev, void *data, for (i = 0; i < FF_MEMLESS_EFFECTS; i++) ml->states[i].effect = &ff->effects[i]; + ff->private = no_free_ptr(ml); + return 0; } EXPORT_SYMBOL_GPL(input_ff_create_memless); -- 2.51.0 From 4e3929ce6cc13b50e3975e8b243d2fcb17b63c64 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 6 Nov 2024 23:15:32 -0800 Subject: [PATCH 08/16] Input: mt - convert locking to guard notation Use guard() notation instead of explicitly acquiring and releasing spinlocks to simplify the code and ensure that all locks are released. Link: https://lore.kernel.org/r/20241107071538.195340-6-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/input-mt.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index 6b04a674f832..45e41fc9059c 100644 --- a/drivers/input/input-mt.c +++ b/drivers/input/input-mt.c @@ -285,14 +285,10 @@ void input_mt_drop_unused(struct input_dev *dev) struct input_mt *mt = dev->mt; if (mt) { - unsigned long flags; - - spin_lock_irqsave(&dev->event_lock, flags); + guard(spinlock_irqsave)(&dev->event_lock); __input_mt_drop_unused(dev, mt); mt->frame++; - - spin_unlock_irqrestore(&dev->event_lock, flags); } } EXPORT_SYMBOL(input_mt_drop_unused); @@ -339,11 +335,8 @@ void input_mt_sync_frame(struct input_dev *dev) return; if (mt->flags & INPUT_MT_DROP_UNUSED) { - unsigned long flags; - - spin_lock_irqsave(&dev->event_lock, flags); + guard(spinlock_irqsave)(&dev->event_lock); __input_mt_drop_unused(dev, mt); - spin_unlock_irqrestore(&dev->event_lock, flags); } if ((mt->flags & INPUT_MT_POINTER) && !(mt->flags & INPUT_MT_SEMI_MT)) -- 2.51.0 From 5bb6e29a2a5a01d916052fbc5398ed8c2c5377f0 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 6 Nov 2024 23:15:33 -0800 Subject: [PATCH 09/16] Input: mt - make use of __free() cleanup facility Annotate allocated memory with __free(kfree) to simplify the code and make sure memory is released appropriately. Link: https://lore.kernel.org/r/20241107071538.195340-7-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/input-mt.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index 45e41fc9059c..337006dd9dcf 100644 --- a/drivers/input/input-mt.c +++ b/drivers/input/input-mt.c @@ -39,20 +39,20 @@ static void copy_abs(struct input_dev *dev, unsigned int dst, unsigned int src) int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots, unsigned int flags) { - struct input_mt *mt = dev->mt; - int i; - if (!num_slots) return 0; - if (mt) - return mt->num_slots != num_slots ? -EINVAL : 0; + + if (dev->mt) + return dev->mt->num_slots != num_slots ? -EINVAL : 0; + /* Arbitrary limit for avoiding too large memory allocation. */ if (num_slots > 1024) return -EINVAL; - mt = kzalloc(struct_size(mt, slots, num_slots), GFP_KERNEL); + struct input_mt *mt __free(kfree) = + kzalloc(struct_size(mt, slots, num_slots), GFP_KERNEL); if (!mt) - goto err_mem; + return -ENOMEM; mt->num_slots = num_slots; mt->flags = flags; @@ -86,21 +86,18 @@ int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots, unsigned int n2 = num_slots * num_slots; mt->red = kcalloc(n2, sizeof(*mt->red), GFP_KERNEL); if (!mt->red) - goto err_mem; + return -ENOMEM; } /* Mark slots as 'inactive' */ - for (i = 0; i < num_slots; i++) + for (unsigned int i = 0; i < num_slots; i++) input_mt_set_value(&mt->slots[i], ABS_MT_TRACKING_ID, -1); /* Mark slots as 'unused' */ mt->frame = 1; - dev->mt = mt; + dev->mt = no_free_ptr(mt); return 0; -err_mem: - kfree(mt); - return -ENOMEM; } EXPORT_SYMBOL(input_mt_init_slots); -- 2.51.0 From f951e94247e2e0cce9b28526b7e25ad95785e8c1 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 6 Nov 2024 23:15:34 -0800 Subject: [PATCH 10/16] Input: poller - convert locking to guard notation Use guard() notation instead of explicitly acquiring and releasing mutex to simplify the code and ensure that it is released. Link: https://lore.kernel.org/r/20241107071538.195340-8-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/input-poller.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/input/input-poller.c b/drivers/input/input-poller.c index 688e3cb1c2a0..9c57713a6151 100644 --- a/drivers/input/input-poller.c +++ b/drivers/input/input-poller.c @@ -162,7 +162,7 @@ static ssize_t input_dev_set_poll_interval(struct device *dev, if (interval > poller->poll_interval_max) return -EINVAL; - mutex_lock(&input->mutex); + guard(mutex)(&input->mutex); poller->poll_interval = interval; @@ -172,8 +172,6 @@ static ssize_t input_dev_set_poll_interval(struct device *dev, input_dev_poller_queue_work(poller); } - mutex_unlock(&input->mutex); - return count; } -- 2.51.0 From 21d8dd0daf4cf4627a0c4b813e0f91bcda67598a Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Wed, 6 Nov 2024 23:15:35 -0800 Subject: [PATCH 11/16] Input: use guard notation in input core Switch input core to use "guard" notation when acquiring spinlocks and mutexes to simplify the code and ensure that locks are automatically released when control leaves critical section. Link: https://lore.kernel.org/r/20241107071538.195340-9-dmitry.torokhov@gmail.com Signed-off-by: Dmitry Torokhov --- drivers/input/input.c | 339 ++++++++++++++++-------------------------- 1 file changed, 131 insertions(+), 208 deletions(-) diff --git a/drivers/input/input.c b/drivers/input/input.c index 7f0477e04ad2..c9e3ac64bcd0 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -115,23 +115,23 @@ static void input_pass_values(struct input_dev *dev, lockdep_assert_held(&dev->event_lock); - rcu_read_lock(); + scoped_guard(rcu) { + handle = rcu_dereference(dev->grab); + if (handle) { + count = handle->handle_events(handle, vals, count); + break; + } - handle = rcu_dereference(dev->grab); - if (handle) { - count = handle->handle_events(handle, vals, count); - } else { - list_for_each_entry_rcu(handle, &dev->h_list, d_node) + list_for_each_entry_rcu(handle, &dev->h_list, d_node) { if (handle->open) { count = handle->handle_events(handle, vals, count); if (!count) break; } + } } - rcu_read_unlock(); - /* trigger auto repeat for key events */ if (test_bit(EV_REP, dev->evbit) && test_bit(EV_KEY, dev->evbit)) { for (v = vals; v != vals + count; v++) { @@ -390,13 +390,9 @@ void input_handle_event(struct input_dev *dev, void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { - unsigned long flags; - if (is_event_supported(type, dev->evbit, EV_MAX)) { - - spin_lock_irqsave(&dev->event_lock, flags); + guard(spinlock_irqsave)(&dev->event_lock); input_handle_event(dev, type, code, value); - spin_unlock_irqrestore(&dev->event_lock, flags); } } EXPORT_SYMBOL(input_event); @@ -417,18 +413,15 @@ void input_inject_event(struct input_handle *handle, { struct input_dev *dev = handle->dev; struct input_handle *grab; - unsigned long flags; if (is_event_supported(type, dev->evbit, EV_MAX)) { - spin_lock_irqsave(&dev->event_lock, flags); + guard(spinlock_irqsave)(&dev->event_lock); + guard(rcu)(); - rcu_read_lock(); grab = rcu_dereference(dev->grab); if (!grab || grab == handle) input_handle_event(dev, type, code, value); - rcu_read_unlock(); - spin_unlock_irqrestore(&dev->event_lock, flags); } } EXPORT_SYMBOL(input_inject_event); @@ -526,22 +519,15 @@ EXPORT_SYMBOL(input_copy_abs); int input_grab_device(struct input_handle *handle) { struct input_dev *dev = handle->dev; - int retval; - retval = mutex_lock_interruptible(&dev->mutex); - if (retval) - return retval; + scoped_cond_guard(mutex_intr, return -EINTR, &dev->mutex) { + if (dev->grab) + return -EBUSY; - if (dev->grab) { - retval = -EBUSY; - goto out; + rcu_assign_pointer(dev->grab, handle); } - rcu_assign_pointer(dev->grab, handle); - - out: - mutex_unlock(&dev->mutex); - return retval; + return 0; } EXPORT_SYMBOL(input_grab_device); @@ -576,9 +562,8 @@ void input_release_device(struct input_handle *handle) { struct input_dev *dev = handle->dev; - mutex_lock(&dev->mutex); + guard(mutex)(&dev->mutex); __input_release_device(handle); - mutex_unlock(&dev->mutex); } EXPORT_SYMBOL(input_release_device); @@ -592,67 +577,57 @@ EXPORT_SYMBOL(input_release_device); int input_open_device(struct input_handle *handle) { struct input_dev *dev = handle->dev; - int retval; - - retval = mutex_lock_interruptible(&dev->mutex); - if (retval) - return retval; - - if (dev->going_away) { - retval = -ENODEV; - goto out; - } + int error; - handle->open++; + scoped_cond_guard(mutex_intr, return -EINTR, &dev->mutex) { + if (dev->going_away) + return -ENODEV; - if (handle->handler->passive_observer) - goto out; + handle->open++; - if (dev->users++ || dev->inhibited) { - /* - * Device is already opened and/or inhibited, - * so we can exit immediately and report success. - */ - goto out; - } + if (handle->handler->passive_observer) + return 0; - if (dev->open) { - retval = dev->open(dev); - if (retval) { - dev->users--; - handle->open--; + if (dev->users++ || dev->inhibited) { /* - * Make sure we are not delivering any more events - * through this handle + * Device is already opened and/or inhibited, + * so we can exit immediately and report success. */ - synchronize_rcu(); - goto out; + return 0; } - } - if (dev->poller) - input_dev_poller_start(dev->poller); + if (dev->open) { + error = dev->open(dev); + if (error) { + dev->users--; + handle->open--; + /* + * Make sure we are not delivering any more + * events through this handle. + */ + synchronize_rcu(); + return error; + } + } - out: - mutex_unlock(&dev->mutex); - return retval; + if (dev->poller) + input_dev_poller_start(dev->poller); + } + + return 0; } EXPORT_SYMBOL(input_open_device); int input_flush_device(struct input_handle *handle, struct file *file) { struct input_dev *dev = handle->dev; - int retval; - retval = mutex_lock_interruptible(&dev->mutex); - if (retval) - return retval; - - if (dev->flush) - retval = dev->flush(dev, file); + scoped_cond_guard(mutex_intr, return -EINTR, &dev->mutex) { + if (dev->flush) + return dev->flush(dev, file); + } - mutex_unlock(&dev->mutex); - return retval; + return 0; } EXPORT_SYMBOL(input_flush_device); @@ -667,7 +642,7 @@ void input_close_device(struct input_handle *handle) { struct input_dev *dev = handle->dev; - mutex_lock(&dev->mutex); + guard(mutex)(&dev->mutex); __input_release_device(handle); @@ -688,8 +663,6 @@ void input_close_device(struct input_handle *handle) */ synchronize_rcu(); } - - mutex_unlock(&dev->mutex); } EXPORT_SYMBOL(input_close_device); @@ -726,11 +699,10 @@ static void input_disconnect_device(struct input_dev *dev) * not to protect access to dev->going_away but rather to ensure * that there are no threads in the middle of input_open_device() */ - mutex_lock(&dev->mutex); - dev->going_away = true; - mutex_unlock(&dev->mutex); + scoped_guard(mutex, &dev->mutex) + dev->going_away = true; - spin_lock_irq(&dev->event_lock); + guard(spinlock_irq)(&dev->event_lock); /* * Simulate keyup events for all pressed keys so that handlers @@ -743,8 +715,6 @@ static void input_disconnect_device(struct input_dev *dev) list_for_each_entry(handle, &dev->h_list, d_node) handle->open = 0; - - spin_unlock_irq(&dev->event_lock); } /** @@ -901,14 +871,9 @@ static int input_default_setkeycode(struct input_dev *dev, */ int input_get_keycode(struct input_dev *dev, struct input_keymap_entry *ke) { - unsigned long flags; - int retval; + guard(spinlock_irqsave)(&dev->event_lock); - spin_lock_irqsave(&dev->event_lock, flags); - retval = dev->getkeycode(dev, ke); - spin_unlock_irqrestore(&dev->event_lock, flags); - - return retval; + return dev->getkeycode(dev, ke); } EXPORT_SYMBOL(input_get_keycode); @@ -923,18 +888,17 @@ EXPORT_SYMBOL(input_get_keycode); int input_set_keycode(struct input_dev *dev, const struct input_keymap_entry *ke) { - unsigned long flags; unsigned int old_keycode; - int retval; + int error; if (ke->keycode > KEY_MAX) return -EINVAL; - spin_lock_irqsave(&dev->event_lock, flags); + guard(spinlock_irqsave)(&dev->event_lock); - retval = dev->setkeycode(dev, ke, &old_keycode); - if (retval) - goto out; + error = dev->setkeycode(dev, ke, &old_keycode); + if (error) + return error; /* Make sure KEY_RESERVED did not get enabled. */ __clear_bit(KEY_RESERVED, dev->keybit); @@ -962,10 +926,7 @@ int input_set_keycode(struct input_dev *dev, EV_SYN, SYN_REPORT, 1); } - out: - spin_unlock_irqrestore(&dev->event_lock, flags); - - return retval; + return 0; } EXPORT_SYMBOL(input_set_keycode); @@ -1799,26 +1760,21 @@ static void input_dev_toggle(struct input_dev *dev, bool activate) */ void input_reset_device(struct input_dev *dev) { - unsigned long flags; - - mutex_lock(&dev->mutex); - spin_lock_irqsave(&dev->event_lock, flags); + guard(mutex)(&dev->mutex); + guard(spinlock_irqsave)(&dev->event_lock); input_dev_toggle(dev, true); if (input_dev_release_keys(dev)) input_handle_event(dev, EV_SYN, SYN_REPORT, 1); - - spin_unlock_irqrestore(&dev->event_lock, flags); - mutex_unlock(&dev->mutex); } EXPORT_SYMBOL(input_reset_device); static int input_inhibit_device(struct input_dev *dev) { - mutex_lock(&dev->mutex); + guard(mutex)(&dev->mutex); if (dev->inhibited) - goto out; + return 0; if (dev->users) { if (dev->close) @@ -1827,54 +1783,50 @@ static int input_inhibit_device(struct input_dev *dev) input_dev_poller_stop(dev->poller); } - spin_lock_irq(&dev->event_lock); - input_mt_release_slots(dev); - input_dev_release_keys(dev); - input_handle_event(dev, EV_SYN, SYN_REPORT, 1); - input_dev_toggle(dev, false); - spin_unlock_irq(&dev->event_lock); + scoped_guard(spinlock_irq, &dev->event_lock) { + input_mt_release_slots(dev); + input_dev_release_keys(dev); + input_handle_event(dev, EV_SYN, SYN_REPORT, 1); + input_dev_toggle(dev, false); + } dev->inhibited = true; -out: - mutex_unlock(&dev->mutex); return 0; } static int input_uninhibit_device(struct input_dev *dev) { - int ret = 0; + int error; - mutex_lock(&dev->mutex); + guard(mutex)(&dev->mutex); if (!dev->inhibited) - goto out; + return 0; if (dev->users) { if (dev->open) { - ret = dev->open(dev); - if (ret) - goto out; + error = dev->open(dev); + if (error) + return error; } if (dev->poller) input_dev_poller_start(dev->poller); } dev->inhibited = false; - spin_lock_irq(&dev->event_lock); - input_dev_toggle(dev, true); - spin_unlock_irq(&dev->event_lock); -out: - mutex_unlock(&dev->mutex); - return ret; + scoped_guard(spinlock_irq, &dev->event_lock) + input_dev_toggle(dev, true); + + return 0; } static int input_dev_suspend(struct device *dev) { struct input_dev *input_dev = to_input_dev(dev); - spin_lock_irq(&input_dev->event_lock); + guard(spinlock_irq)(&input_dev->event_lock); /* * Keys that are pressed now are unlikely to be @@ -1886,8 +1838,6 @@ static int input_dev_suspend(struct device *dev) /* Turn off LEDs and sounds, if any are active. */ input_dev_toggle(input_dev, false); - spin_unlock_irq(&input_dev->event_lock); - return 0; } @@ -1895,13 +1845,11 @@ static int input_dev_resume(struct device *dev) { struct input_dev *input_dev = to_input_dev(dev); - spin_lock_irq(&input_dev->event_lock); + guard(spinlock_irq)(&input_dev->event_lock); /* Restore state of LEDs and sounds, if any were active. */ input_dev_toggle(input_dev, true); - spin_unlock_irq(&input_dev->event_lock); - return 0; } @@ -1909,7 +1857,7 @@ static int input_dev_freeze(struct device *dev) { struct input_dev *input_dev = to_input_dev(dev); - spin_lock_irq(&input_dev->event_lock); + guard(spinlock_irq)(&input_dev->event_lock); /* * Keys that are pressed now are unlikely to be @@ -1918,8 +1866,6 @@ static int input_dev_freeze(struct device *dev) if (input_dev_release_keys(input_dev)) input_handle_event(input_dev, EV_SYN, SYN_REPORT, 1); - spin_unlock_irq(&input_dev->event_lock); - return 0; } @@ -1927,13 +1873,11 @@ static int input_dev_poweroff(struct device *dev) { struct input_dev *input_dev = to_input_dev(dev); - spin_lock_irq(&input_dev->event_lock); + guard(spinlock_irq)(&input_dev->event_lock); /* Turn off LEDs and sounds, if any are active. */ input_dev_toggle(input_dev, false); - spin_unlock_irq(&input_dev->event_lock); - return 0; } @@ -2274,18 +2218,16 @@ static void __input_unregister_device(struct input_dev *dev) input_disconnect_device(dev); - mutex_lock(&input_mutex); - - list_for_each_entry_safe(handle, next, &dev->h_list, d_node) - handle->handler->disconnect(handle); - WARN_ON(!list_empty(&dev->h_list)); + scoped_guard(mutex, &input_mutex) { + list_for_each_entry_safe(handle, next, &dev->h_list, d_node) + handle->handler->disconnect(handle); + WARN_ON(!list_empty(&dev->h_list)); - del_timer_sync(&dev->timer); - list_del_init(&dev->node); + del_timer_sync(&dev->timer); + list_del_init(&dev->node); - input_wakeup_procfs_readers(); - - mutex_unlock(&input_mutex); + input_wakeup_procfs_readers(); + } device_del(&dev->dev); } @@ -2308,9 +2250,8 @@ static void devm_input_device_unregister(struct device *dev, void *res) static void input_repeat_key(struct timer_list *t) { struct input_dev *dev = from_timer(dev, t, timer); - unsigned long flags; - spin_lock_irqsave(&dev->event_lock, flags); + guard(spinlock_irqsave)(&dev->event_lock); if (!dev->inhibited && test_bit(dev->repeat_key, dev->key) && @@ -2324,8 +2265,6 @@ static void input_repeat_key(struct timer_list *t) mod_timer(&dev->timer, jiffies + msecs_to_jiffies(dev->rep[REP_PERIOD])); } - - spin_unlock_irqrestore(&dev->event_lock, flags); } /** @@ -2370,10 +2309,10 @@ static int input_device_tune_vals(struct input_dev *dev) if (!vals) return -ENOMEM; - spin_lock_irq(&dev->event_lock); - dev->max_vals = max_vals; - swap(dev->vals, vals); - spin_unlock_irq(&dev->event_lock); + scoped_guard(spinlock_irq, &dev->event_lock) { + dev->max_vals = max_vals; + swap(dev->vals, vals); + } /* Because of swap() above, this frees the old vals memory */ kfree(vals); @@ -2465,18 +2404,15 @@ int input_register_device(struct input_dev *dev) path ? path : "N/A"); kfree(path); - error = mutex_lock_interruptible(&input_mutex); - if (error) - goto err_device_del; + error = -EINTR; + scoped_cond_guard(mutex_intr, goto err_device_del, &input_mutex) { + list_add_tail(&dev->node, &input_dev_list); - list_add_tail(&dev->node, &input_dev_list); + list_for_each_entry(handler, &input_handler_list, node) + input_attach_handler(dev, handler); - list_for_each_entry(handler, &input_handler_list, node) - input_attach_handler(dev, handler); - - input_wakeup_procfs_readers(); - - mutex_unlock(&input_mutex); + input_wakeup_procfs_readers(); + } if (dev->devres_managed) { dev_dbg(dev->dev.parent, "%s: registering %s with devres.\n", @@ -2556,20 +2492,17 @@ int input_register_handler(struct input_handler *handler) if (error) return error; - INIT_LIST_HEAD(&handler->h_list); + scoped_cond_guard(mutex_intr, return -EINTR, &input_mutex) { + INIT_LIST_HEAD(&handler->h_list); - error = mutex_lock_interruptible(&input_mutex); - if (error) - return error; - - list_add_tail(&handler->node, &input_handler_list); + list_add_tail(&handler->node, &input_handler_list); - list_for_each_entry(dev, &input_dev_list, node) - input_attach_handler(dev, handler); + list_for_each_entry(dev, &input_dev_list, node) + input_attach_handler(dev, handler); - input_wakeup_procfs_readers(); + input_wakeup_procfs_readers(); + } - mutex_unlock(&input_mutex); return 0; } EXPORT_SYMBOL(input_register_handler); @@ -2585,7 +2518,7 @@ void input_unregister_handler(struct input_handler *handler) { struct input_handle *handle, *next; - mutex_lock(&input_mutex); + guard(mutex)(&input_mutex); list_for_each_entry_safe(handle, next, &handler->h_list, h_node) handler->disconnect(handle); @@ -2594,8 +2527,6 @@ void input_unregister_handler(struct input_handler *handler) list_del_init(&handler->node); input_wakeup_procfs_readers(); - - mutex_unlock(&input_mutex); } EXPORT_SYMBOL(input_unregister_handler); @@ -2615,19 +2546,17 @@ int input_handler_for_each_handle(struct input_handler *handler, void *data, int (*fn)(struct input_handle *, void *)) { struct input_handle *handle; - int retval = 0; + int retval; - rcu_read_lock(); + guard(rcu)(); list_for_each_entry_rcu(handle, &handler->h_list, h_node) { retval = fn(handle, data); if (retval) - break; + return retval; } - rcu_read_unlock(); - - return retval; + return 0; } EXPORT_SYMBOL(input_handler_for_each_handle); @@ -2715,27 +2644,22 @@ int input_register_handle(struct input_handle *handle) { struct input_handler *handler = handle->handler; 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(). */ - error = mutex_lock_interruptible(&dev->mutex); - if (error) - return error; - - /* - * Filters go to the head of the list, normal handlers - * to the tail. - */ - if (handler->filter) - list_add_rcu(&handle->d_node, &dev->h_list); - else - list_add_tail_rcu(&handle->d_node, &dev->h_list); - - mutex_unlock(&dev->mutex); + scoped_cond_guard(mutex_intr, return -EINTR, &dev->mutex) { + /* + * Filters go to the head of the list, normal handlers + * to the tail. + */ + if (handler->filter) + list_add_rcu(&handle->d_node, &dev->h_list); + else + list_add_tail_rcu(&handle->d_node, &dev->h_list); + } /* * Since we are supposed to be called from ->connect() @@ -2771,9 +2695,8 @@ void input_unregister_handle(struct input_handle *handle) /* * Take dev->mutex to prevent race with input_release_device(). */ - mutex_lock(&dev->mutex); - list_del_rcu(&handle->d_node); - mutex_unlock(&dev->mutex); + scoped_guard(mutex, &dev->mutex) + list_del_rcu(&handle->d_node); synchronize_rcu(); } -- 2.51.0 From 7ef9bdec9a22ad48a76e0c446d54b2274eaf2fca Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 14 Jan 2025 13:40:22 -0800 Subject: [PATCH 12/16] Input: Use str_enable_disable-like helpers Replace ternary (condition ? "enable" : "disable") syntax with helpers from string_choices.h because: 1. Simple function call with one argument is easier to read. Ternary operator has three arguments and with wrapping might lead to quite long code. 2. Is slightly shorter thus also easier to read. 3. It brings uniformity in the text - same string. 4. Allows deduping by the linker, which results in a smaller binary file. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250114192701.912430-1-krzysztof.kozlowski@linaro.org Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/dlink-dir685-touchkeys.c | 3 ++- drivers/input/keyboard/lm8323.c | 3 ++- drivers/input/misc/max77693-haptic.c | 3 ++- drivers/input/misc/regulator-haptic.c | 3 ++- drivers/input/mouse/elan_i2c_core.c | 3 ++- drivers/input/touchscreen/egalax_ts.c | 3 ++- 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/input/keyboard/dlink-dir685-touchkeys.c b/drivers/input/keyboard/dlink-dir685-touchkeys.c index 993cdbda509e..4184dd2eaeeb 100644 --- a/drivers/input/keyboard/dlink-dir685-touchkeys.c +++ b/drivers/input/keyboard/dlink-dir685-touchkeys.c @@ -14,6 +14,7 @@ #include #include #include +#include #include struct dir685_touchkeys { @@ -48,7 +49,7 @@ static irqreturn_t dir685_tk_irq_thread(int irq, void *data) changed = tk->cur_key ^ key; for_each_set_bit(i, &changed, num_bits) { dev_dbg(tk->dev, "key %d is %s\n", i, - test_bit(i, &key) ? "down" : "up"); + str_down_up(test_bit(i, &key))); input_report_key(tk->input, tk->codes[i], test_bit(i, &key)); } diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c index e26bf2956344..e19442c6f80f 100644 --- a/drivers/input/keyboard/lm8323.c +++ b/drivers/input/keyboard/lm8323.c @@ -21,6 +21,7 @@ #include #include #include +#include /* Commands to send to the chip. */ #define LM8323_CMD_READ_ID 0x80 /* Read chip ID. */ @@ -269,7 +270,7 @@ static void process_keys(struct lm8323_chip *lm) unsigned short keycode = lm->keymap[key]; dev_vdbg(&lm->client->dev, "key 0x%02x %s\n", - key, isdown ? "down" : "up"); + key, str_down_up(isdown)); if (lm->kp_enabled) { input_event(lm->idev, EV_MSC, MSC_SCAN, key); diff --git a/drivers/input/misc/max77693-haptic.c b/drivers/input/misc/max77693-haptic.c index 0e646f1b257b..cdb9be737e48 100644 --- a/drivers/input/misc/max77693-haptic.c +++ b/drivers/input/misc/max77693-haptic.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -94,7 +95,7 @@ static int max77843_haptic_bias(struct max77693_haptic *haptic, bool on) on << MAINCTRL1_BIASEN_SHIFT); if (error) { dev_err(haptic->dev, "failed to %s bias: %d\n", - on ? "enable" : "disable", error); + str_enable_disable(on), error); return error; } diff --git a/drivers/input/misc/regulator-haptic.c b/drivers/input/misc/regulator-haptic.c index 3666ba6d1f30..9711f5c7c78a 100644 --- a/drivers/input/misc/regulator-haptic.c +++ b/drivers/input/misc/regulator-haptic.c @@ -14,6 +14,7 @@ #include #include #include +#include #define MAX_MAGNITUDE_SHIFT 16 @@ -44,7 +45,7 @@ static int regulator_haptic_toggle(struct regulator_haptic *haptic, bool on) if (error) { dev_err(haptic->dev, "failed to switch regulator %s: %d\n", - on ? "on" : "off", error); + str_on_off(on), error); return error; } diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c index a841883660fb..fee1796da3d0 100644 --- a/drivers/input/mouse/elan_i2c_core.c +++ b/drivers/input/mouse/elan_i2c_core.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -199,7 +200,7 @@ static int elan_set_power(struct elan_tp_data *data, bool on) } while (--repeat > 0); dev_err(&data->client->dev, "failed to set power %s: %d\n", - on ? "on" : "off", error); + str_on_off(on), error); return error; } diff --git a/drivers/input/touchscreen/egalax_ts.c b/drivers/input/touchscreen/egalax_ts.c index f4e950920e84..eb3cc2befcdf 100644 --- a/drivers/input/touchscreen/egalax_ts.c +++ b/drivers/input/touchscreen/egalax_ts.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -102,7 +103,7 @@ static irqreturn_t egalax_ts_interrupt(int irq, void *dev_id) input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, down); dev_dbg(&client->dev, "%s id:%d x:%d y:%d z:%d", - down ? "down" : "up", id, x, y, z); + str_down_up(down), id, x, y, z); if (down) { input_report_abs(input_dev, ABS_MT_POSITION_X, x); -- 2.51.0 From d3561c4098de9666b87630ad3f090b41e67cdd62 Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Tue, 14 Jan 2025 13:41:06 -0800 Subject: [PATCH 13/16] Input: joystick - use str_off_on() helper in sw_connect() Remove hard-coded strings by using the str_off_on() helper. Signed-off-by: Thorsten Blum Link: https://lore.kernel.org/r/20241202154603.1193-2-thorsten.blum@linux.dev Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/sidewinder.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c index f6e92db4d789..3a5873e5fcb3 100644 --- a/drivers/input/joystick/sidewinder.c +++ b/drivers/input/joystick/sidewinder.c @@ -14,6 +14,7 @@ #include #include #include +#include #define DRIVER_DESC "Microsoft SideWinder joystick family driver" @@ -677,7 +678,7 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) case 48: /* Ambiguous */ if (j == 14) { /* ID length 14*3 -> FFP */ sw->type = SW_ID_FFP; - sprintf(comment, " [AC %s]", sw_get_bits(idbuf,38,1,3) ? "off" : "on"); + sprintf(comment, " [AC %s]", str_off_on(sw_get_bits(idbuf,38,1,3))); } else sw->type = SW_ID_PP; break; -- 2.51.0 From 92600f3295ff571890c981d886c6544030cc05f3 Mon Sep 17 00:00:00 2001 From: "Pierre-Loup A. Griffais" Date: Thu, 16 Jan 2025 10:29:53 -0800 Subject: [PATCH 14/16] Input: xpad - add QH Electronics VID/PID Add support for QH Electronics Xbox 360-compatible controller Signed-off-by: Pierre-Loup A. Griffais Signed-off-by: Vicki Pfau Link: https://lore.kernel.org/r/20250116012518.3476735-1-vi@endrift.com Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index ff9bc87f2f70..56ae0847cbfd 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -305,6 +305,7 @@ static const struct xpad_device { { 0x1689, 0xfe00, "Razer Sabertooth", 0, XTYPE_XBOX360 }, { 0x17ef, 0x6182, "Lenovo Legion Controller for Windows", 0, XTYPE_XBOX360 }, { 0x1949, 0x041a, "Amazon Game Controller", 0, XTYPE_XBOX360 }, + { 0x1a86, 0xe310, "QH Electronics Controller", 0, XTYPE_XBOX360 }, { 0x1bad, 0x0002, "Harmonix Rock Band Guitar", 0, XTYPE_XBOX360 }, { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, { 0x1bad, 0x0130, "Ion Drum Rocker", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, @@ -514,6 +515,7 @@ static const struct usb_device_id xpad_table[] = { XPAD_XBOX360_VENDOR(0x1689), /* Razer Onza */ XPAD_XBOX360_VENDOR(0x17ef), /* Lenovo */ XPAD_XBOX360_VENDOR(0x1949), /* Amazon controllers */ + XPAD_XBOX360_VENDOR(0x1a86), /* QH Electronics */ XPAD_XBOX360_VENDOR(0x1bad), /* Harmonix Rock Band guitar and drums */ XPAD_XBOX360_VENDOR(0x20d6), /* PowerA controllers */ XPAD_XBOXONE_VENDOR(0x20d6), /* PowerA controllers */ -- 2.51.0 From 66372fa9936088bf29c4f47907efeff03c51a2c8 Mon Sep 17 00:00:00 2001 From: Leonardo Brondani Schenkel Date: Fri, 17 Jan 2025 16:46:11 -0800 Subject: [PATCH 15/16] Input: xpad - improve name of 8BitDo controller 2dc8:3106 8BitDo Pro 2 Wired Controller shares the same USB identifier (2dc8:3106) as a different device, so amend name to reflect that and reduce confusion as the user might think the controller was misdetected. Because Pro 2 Wired will not work in XTYPE_XBOXONE mode (button presses won't register), tagging it as XTYPE_XBOX360 remains appropriate. Signed-off-by: Leonardo Brondani Schenkel Signed-off-by: Pavel Rojtberg Link: https://lore.kernel.org/r/20250107192830.414709-2-rojtberg@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 56ae0847cbfd..f173f41430e4 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -374,7 +374,7 @@ static const struct xpad_device { { 0x294b, 0x3303, "Snakebyte GAMEPAD BASE X", 0, XTYPE_XBOXONE }, { 0x294b, 0x3404, "Snakebyte GAMEPAD RGB X", 0, XTYPE_XBOXONE }, { 0x2dc8, 0x2000, "8BitDo Pro 2 Wired Controller fox Xbox", 0, XTYPE_XBOXONE }, - { 0x2dc8, 0x3106, "8BitDo Pro 2 Wired Controller", 0, XTYPE_XBOX360 }, + { 0x2dc8, 0x3106, "8BitDo Ultimate Wireless / Pro 2 Wired Controller", 0, XTYPE_XBOX360 }, { 0x2dc8, 0x310a, "8BitDo Ultimate 2C Wireless Controller", 0, XTYPE_XBOX360 }, { 0x2e24, 0x0652, "Hyperkin Duke X-Box One pad", 0, XTYPE_XBOXONE }, { 0x31e3, 0x1100, "Wooting One", 0, XTYPE_XBOX360 }, -- 2.51.0 From 222f3390c15c4452a9f7e26f5b7d9138e75d00d5 Mon Sep 17 00:00:00 2001 From: Jack Greiner Date: Fri, 17 Jan 2025 16:51:58 -0800 Subject: [PATCH 16/16] Input: xpad - add support for wooting two he (arm) Add Wooting Two HE (ARM) to the list of supported devices. Signed-off-by: Jack Greiner Signed-off-by: Pavel Rojtberg Link: https://lore.kernel.org/r/20250107192830.414709-3-rojtberg@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov --- drivers/input/joystick/xpad.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index f173f41430e4..619c79a7fb46 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -381,6 +381,7 @@ static const struct xpad_device { { 0x31e3, 0x1200, "Wooting Two", 0, XTYPE_XBOX360 }, { 0x31e3, 0x1210, "Wooting Lekker", 0, XTYPE_XBOX360 }, { 0x31e3, 0x1220, "Wooting Two HE", 0, XTYPE_XBOX360 }, + { 0x31e3, 0x1230, "Wooting Two HE (ARM)", 0, XTYPE_XBOX360 }, { 0x31e3, 0x1300, "Wooting 60HE (AVR)", 0, XTYPE_XBOX360 }, { 0x31e3, 0x1310, "Wooting 60HE (ARM)", 0, XTYPE_XBOX360 }, { 0x3285, 0x0607, "Nacon GC-100", 0, XTYPE_XBOX360 }, -- 2.51.0