Commit 88e969fc authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull input updates from Dmitry Torokhov:

 - more conversions to the guard notation in the input core

 - a fix for NXP BBNSM power key driver to clean up wake IRQ after
   unbinding

 - several new vendor/device ID pairs added to xpad game controller
   driver

 - several drivers switched to using str_enable_disable and similar
   helpers instead of open-coding

 - add mapping for F23 to atkbd driver so that MS "Copilot" key shortcut
   works out of the box (if userspace is ready to handle it)

 - evbug input handler has been removed (debugging through evdev is
   strongly preferred to dumping all events into the kernel log).

* tag 'input-for-v6.14-rc0' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (22 commits)
  Input: synaptics - fix crash when enabling pass-through port
  Input: atkbd - map F23 key to support default copilot shortcut
  Input: xpad - add support for Nacon Evol-X Xbox One Controller
  Input: xpad - add unofficial Xbox 360 wireless receiver clone
  Input: xpad - add support for wooting two he (arm)
  Input: xpad - improve name of 8BitDo controller 2dc8:3106
  Input: xpad - add QH Electronics VID/PID
  Input: joystick - use str_off_on() helper in sw_connect()
  Input: Use str_enable_disable-like helpers
  Input: use guard notation in input core
  Input: poller - convert locking to guard notation
  Input: mt - make use of __free() cleanup facility
  Input: mt - convert locking to guard notation
  Input: ff-memless - make use of __free() cleanup facility
  Input: ff-memless - convert locking to guard notation
  Input: ff-core - make use of __free() cleanup facility
  Input: ff-core - convert locking to guard notation
  Input: remove evbug driver
  Input: mma8450 - add chip ID check in probe
  Input: bbnsm_pwrkey - add remove hook
  ...
parents 27c02784 25768de5
Loading
Loading
Loading
Loading
+0 −14
Original line number Diff line number Diff line
@@ -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
+0 −1
Original line number Diff line number Diff line
@@ -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/

drivers/input/evbug.c

deleted100644 → 0
+0 −100
Original line number Diff line number Diff line
// 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 <linux/slab.h>
#include <linux/module.h>
#include <linux/input.h>
#include <linux/init.h>
#include <linux/device.h>

MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
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);
+36 −55
Original line number Diff line number Diff line
@@ -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);
	scoped_guard(spinlock_irq, &dev->event_lock) {
		ff->effects[id] = *effect;
		ff->effect_owners[id] = file;
	spin_unlock_irq(&dev->event_lock);
	}

 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);
	scoped_guard(spinlock_irq, &dev->event_lock) {
		ff->playback(dev, effect_id, 0);
		ff->effect_owners[effect_id] = NULL;
	spin_unlock_irq(&dev->event_lock);
	}

	if (ff->erase) {
		error = ff->erase(dev, effect_id);
		if (error) {
			spin_lock_irq(&dev->event_lock);
			scoped_guard(spinlock_irq, &dev->event_lock)
				ff->effect_owners[effect_id] = file;
			spin_unlock_irq(&dev->event_lock);

			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);
@@ -303,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) {
@@ -317,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);
@@ -348,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);
+6 −12
Original line number Diff line number Diff line
@@ -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;
}

@@ -507,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;

@@ -525,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;
@@ -548,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);
Loading