mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-22 23:13:01 +02:00
Input updates for v6.14-rc0
- 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). -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQST2eWILY88ieB2DOtAj56VGEWXnAUCZ5ABwgAKCRBAj56VGEWX nColAQDdu5HPbyeF6ZU6/BqTO1ZhBbcSnaXyDRT0jv0qp0UlQAEA+zc0EPBtx8jE RumALncq1FZkjHpPDUUmlIrTdiFM4gA= =whWY -----END PGP SIGNATURE----- Merge tag 'input-for-v6.14-rc0' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input 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 ...
This commit is contained in:
commit
88e969fc18
|
@ -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
|
||||
|
|
|
@ -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/
|
||||
|
|
|
@ -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 <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);
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
@ -285,14 +282,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 +332,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))
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -115,13 +115,14 @@ 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);
|
||||
} else {
|
||||
list_for_each_entry_rcu(handle, &dev->h_list, d_node)
|
||||
break;
|
||||
}
|
||||
|
||||
list_for_each_entry_rcu(handle, &dev->h_list, d_node) {
|
||||
if (handle->open) {
|
||||
count = handle->handle_events(handle, vals,
|
||||
count);
|
||||
|
@ -129,8 +130,7 @@ static void input_pass_values(struct input_dev *dev,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
/* trigger auto repeat for key events */
|
||||
if (test_bit(EV_REP, dev->evbit) && test_bit(EV_KEY, dev->evbit)) {
|
||||
|
@ -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;
|
||||
|
||||
if (dev->grab) {
|
||||
retval = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
scoped_cond_guard(mutex_intr, return -EINTR, &dev->mutex) {
|
||||
if (dev->grab)
|
||||
return -EBUSY;
|
||||
|
||||
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;
|
||||
int error;
|
||||
|
||||
retval = mutex_lock_interruptible(&dev->mutex);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
if (dev->going_away) {
|
||||
retval = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
scoped_cond_guard(mutex_intr, return -EINTR, &dev->mutex) {
|
||||
if (dev->going_away)
|
||||
return -ENODEV;
|
||||
|
||||
handle->open++;
|
||||
|
||||
if (handle->handler->passive_observer)
|
||||
goto out;
|
||||
return 0;
|
||||
|
||||
if (dev->users++ || dev->inhibited) {
|
||||
/*
|
||||
* Device is already opened and/or inhibited,
|
||||
* so we can exit immediately and report success.
|
||||
*/
|
||||
goto out;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dev->open) {
|
||||
retval = dev->open(dev);
|
||||
if (retval) {
|
||||
error = dev->open(dev);
|
||||
if (error) {
|
||||
dev->users--;
|
||||
handle->open--;
|
||||
/*
|
||||
* Make sure we are not delivering any more events
|
||||
* through this handle
|
||||
* Make sure we are not delivering any more
|
||||
* events through this handle.
|
||||
*/
|
||||
synchronize_rcu();
|
||||
goto out;
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->poller)
|
||||
input_dev_poller_start(dev->poller);
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&dev->mutex);
|
||||
return retval;
|
||||
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;
|
||||
|
||||
scoped_cond_guard(mutex_intr, return -EINTR, &dev->mutex) {
|
||||
if (dev->flush)
|
||||
retval = dev->flush(dev, file);
|
||||
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);
|
||||
scoped_guard(mutex, &dev->mutex)
|
||||
dev->going_away = true;
|
||||
mutex_unlock(&dev->mutex);
|
||||
|
||||
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);
|
||||
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);
|
||||
spin_unlock_irq(&dev->event_lock);
|
||||
}
|
||||
|
||||
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,8 +2218,7 @@ static void __input_unregister_device(struct input_dev *dev)
|
|||
|
||||
input_disconnect_device(dev);
|
||||
|
||||
mutex_lock(&input_mutex);
|
||||
|
||||
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));
|
||||
|
@ -2284,8 +2227,7 @@ static void __input_unregister_device(struct input_dev *dev)
|
|||
list_del_init(&dev->node);
|
||||
|
||||
input_wakeup_procfs_readers();
|
||||
|
||||
mutex_unlock(&input_mutex);
|
||||
}
|
||||
|
||||
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);
|
||||
scoped_guard(spinlock_irq, &dev->event_lock) {
|
||||
dev->max_vals = max_vals;
|
||||
swap(dev->vals, vals);
|
||||
spin_unlock_irq(&dev->event_lock);
|
||||
}
|
||||
|
||||
/* 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_for_each_entry(handler, &input_handler_list, node)
|
||||
input_attach_handler(dev, handler);
|
||||
|
||||
input_wakeup_procfs_readers();
|
||||
|
||||
mutex_unlock(&input_mutex);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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_for_each_entry(dev, &input_dev_list, node)
|
||||
input_attach_handler(dev, handler);
|
||||
|
||||
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,17 +2644,13 @@ 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;
|
||||
|
||||
scoped_cond_guard(mutex_intr, return -EINTR, &dev->mutex) {
|
||||
/*
|
||||
* Filters go to the head of the list, normal handlers
|
||||
* to the tail.
|
||||
|
@ -2734,8 +2659,7 @@ int input_register_handle(struct input_handle *handle)
|
|||
list_add_rcu(&handle->d_node, &dev->h_list);
|
||||
else
|
||||
list_add_tail_rcu(&handle->d_node, &dev->h_list);
|
||||
|
||||
mutex_unlock(&dev->mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
scoped_guard(mutex, &dev->mutex)
|
||||
list_del_rcu(&handle->d_node);
|
||||
mutex_unlock(&dev->mutex);
|
||||
|
||||
synchronize_rcu();
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <linux/input.h>
|
||||
#include <linux/gameport.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/string_choices.h>
|
||||
|
||||
#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;
|
||||
|
|
|
@ -150,6 +150,7 @@ static const struct xpad_device {
|
|||
{ 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 },
|
||||
{ 0x045e, 0x028f, "Microsoft X-Box 360 pad v2", 0, XTYPE_XBOX360 },
|
||||
{ 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
|
||||
{ 0x045e, 0x02a9, "Xbox 360 Wireless Receiver (Unofficial)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
|
||||
{ 0x045e, 0x02d1, "Microsoft X-Box One pad", 0, XTYPE_XBOXONE },
|
||||
{ 0x045e, 0x02dd, "Microsoft X-Box One pad (Firmware 2015)", 0, XTYPE_XBOXONE },
|
||||
{ 0x045e, 0x02e3, "Microsoft X-Box One Elite pad", MAP_PADDLES, XTYPE_XBOXONE },
|
||||
|
@ -305,6 +306,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 },
|
||||
|
@ -373,16 +375,19 @@ 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 },
|
||||
{ 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 },
|
||||
{ 0x3285, 0x0646, "Nacon Pro Compact", 0, XTYPE_XBOXONE },
|
||||
{ 0x3285, 0x0663, "Nacon Evol-X", 0, XTYPE_XBOXONE },
|
||||
{ 0x3537, 0x1004, "GameSir T4 Kaleid", 0, XTYPE_XBOX360 },
|
||||
{ 0x3767, 0x0101, "Fanatec Speedster 3 Forceshock Wheel", 0, XTYPE_XBOX },
|
||||
{ 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX },
|
||||
|
@ -514,6 +519,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 */
|
||||
|
@ -530,6 +536,7 @@ static const struct usb_device_id xpad_table[] = {
|
|||
XPAD_XBOX360_VENDOR(0x2f24), /* GameSir controllers */
|
||||
XPAD_XBOX360_VENDOR(0x31e3), /* Wooting Keyboards */
|
||||
XPAD_XBOX360_VENDOR(0x3285), /* Nacon GC-100 */
|
||||
XPAD_XBOXONE_VENDOR(0x3285), /* Nacon Evol-X */
|
||||
XPAD_XBOX360_VENDOR(0x3537), /* GameSir Controllers */
|
||||
XPAD_XBOXONE_VENDOR(0x3537), /* GameSir Controllers */
|
||||
{ }
|
||||
|
|
|
@ -89,7 +89,7 @@ static const unsigned short atkbd_set2_keycode[ATKBD_KEYMAP_SIZE] = {
|
|||
0, 46, 45, 32, 18, 5, 4, 95, 0, 57, 47, 33, 20, 19, 6,183,
|
||||
0, 49, 48, 35, 34, 21, 7,184, 0, 0, 50, 36, 22, 8, 9,185,
|
||||
0, 51, 37, 23, 24, 11, 10, 0, 0, 52, 53, 38, 39, 25, 12, 0,
|
||||
0, 89, 40, 0, 26, 13, 0, 0, 58, 54, 28, 27, 0, 43, 0, 85,
|
||||
0, 89, 40, 0, 26, 13, 0,193, 58, 54, 28, 27, 0, 43, 0, 85,
|
||||
0, 86, 91, 90, 92, 0, 14, 94, 0, 79,124, 75, 71,121, 0, 0,
|
||||
82, 83, 80, 76, 77, 72, 1, 69, 87, 78, 81, 74, 55, 73, 70, 99,
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string_choices.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <linux/platform_data/lm8323.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string_choices.h>
|
||||
|
||||
/* 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);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/pwm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string_choices.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/mfd/max77693.h>
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
|
||||
#define MMA8450_CTRL_REG1 0x38
|
||||
#define MMA8450_CTRL_REG2 0x39
|
||||
#define MMA8450_ID 0xc6
|
||||
#define MMA8450_WHO_AM_I 0x0f
|
||||
|
||||
static int mma8450_read(struct i2c_client *c, unsigned int off)
|
||||
{
|
||||
|
@ -148,8 +150,20 @@ static void mma8450_close(struct input_dev *input)
|
|||
*/
|
||||
static int mma8450_probe(struct i2c_client *c)
|
||||
{
|
||||
struct i2c_adapter *adapter = c->adapter;
|
||||
struct input_dev *input;
|
||||
int err;
|
||||
int err, client_id;
|
||||
|
||||
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE |
|
||||
I2C_FUNC_SMBUS_BYTE_DATA))
|
||||
return dev_err_probe(&c->dev, -EINVAL,
|
||||
"I2C adapter doesn't support SMBUS BYTE");
|
||||
|
||||
client_id = i2c_smbus_read_byte_data(c, MMA8450_WHO_AM_I);
|
||||
if (client_id != MMA8450_ID)
|
||||
return dev_err_probe(&c->dev, -EINVAL,
|
||||
"unexpected chip ID 0x%x (vs 0x%x)\n",
|
||||
client_id, MMA8450_ID);
|
||||
|
||||
input = devm_input_allocate_device(&c->dev);
|
||||
if (!input)
|
||||
|
|
|
@ -187,6 +187,12 @@ static int bbnsm_pwrkey_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void bbnsm_pwrkey_remove(struct platform_device *pdev)
|
||||
{
|
||||
dev_pm_clear_wake_irq(&pdev->dev);
|
||||
device_init_wakeup(&pdev->dev, false);
|
||||
}
|
||||
|
||||
static int __maybe_unused bbnsm_pwrkey_suspend(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
|
@ -223,6 +229,8 @@ static struct platform_driver bbnsm_pwrkey_driver = {
|
|||
.of_match_table = bbnsm_pwrkey_ids,
|
||||
},
|
||||
.probe = bbnsm_pwrkey_probe,
|
||||
.remove = bbnsm_pwrkey_remove,
|
||||
|
||||
};
|
||||
module_platform_driver(bbnsm_pwrkey_driver);
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string_choices.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/string_choices.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/jiffies.h>
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -665,23 +665,50 @@ static void synaptics_pt_stop(struct serio *serio)
|
|||
priv->pt_port = NULL;
|
||||
}
|
||||
|
||||
static int synaptics_pt_open(struct serio *serio)
|
||||
{
|
||||
struct psmouse *parent = psmouse_from_serio(serio->parent);
|
||||
struct synaptics_data *priv = parent->private;
|
||||
|
||||
guard(serio_pause_rx)(parent->ps2dev.serio);
|
||||
priv->pt_port_open = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void synaptics_pt_close(struct serio *serio)
|
||||
{
|
||||
struct psmouse *parent = psmouse_from_serio(serio->parent);
|
||||
struct synaptics_data *priv = parent->private;
|
||||
|
||||
guard(serio_pause_rx)(parent->ps2dev.serio);
|
||||
priv->pt_port_open = false;
|
||||
}
|
||||
|
||||
static int synaptics_is_pt_packet(u8 *buf)
|
||||
{
|
||||
return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4;
|
||||
}
|
||||
|
||||
static void synaptics_pass_pt_packet(struct serio *ptport, u8 *packet)
|
||||
static void synaptics_pass_pt_packet(struct synaptics_data *priv, u8 *packet)
|
||||
{
|
||||
struct serio *ptport;
|
||||
|
||||
ptport = priv->pt_port;
|
||||
if (!ptport)
|
||||
return;
|
||||
|
||||
serio_interrupt(ptport, packet[1], 0);
|
||||
|
||||
if (priv->pt_port_open) {
|
||||
struct psmouse *child = psmouse_from_serio(ptport);
|
||||
|
||||
if (child && child->state == PSMOUSE_ACTIVATED) {
|
||||
serio_interrupt(ptport, packet[1], 0);
|
||||
if (child->state == PSMOUSE_ACTIVATED) {
|
||||
serio_interrupt(ptport, packet[4], 0);
|
||||
serio_interrupt(ptport, packet[5], 0);
|
||||
if (child->pktsize == 4)
|
||||
serio_interrupt(ptport, packet[2], 0);
|
||||
} else {
|
||||
serio_interrupt(ptport, packet[1], 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -720,6 +747,8 @@ static void synaptics_pt_create(struct psmouse *psmouse)
|
|||
serio->write = synaptics_pt_write;
|
||||
serio->start = synaptics_pt_start;
|
||||
serio->stop = synaptics_pt_stop;
|
||||
serio->open = synaptics_pt_open;
|
||||
serio->close = synaptics_pt_close;
|
||||
serio->parent = psmouse->ps2dev.serio;
|
||||
|
||||
psmouse->pt_activate = synaptics_pt_activate;
|
||||
|
@ -1216,11 +1245,10 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse)
|
|||
|
||||
if (SYN_CAP_PASS_THROUGH(priv->info.capabilities) &&
|
||||
synaptics_is_pt_packet(psmouse->packet)) {
|
||||
if (priv->pt_port)
|
||||
synaptics_pass_pt_packet(priv->pt_port,
|
||||
psmouse->packet);
|
||||
} else
|
||||
synaptics_pass_pt_packet(priv, psmouse->packet);
|
||||
} else {
|
||||
synaptics_process_packet(psmouse);
|
||||
}
|
||||
|
||||
return PSMOUSE_FULL_PACKET;
|
||||
}
|
||||
|
|
|
@ -188,6 +188,7 @@ struct synaptics_data {
|
|||
bool disable_gesture; /* disable gestures */
|
||||
|
||||
struct serio *pt_port; /* Pass-through serio port */
|
||||
bool pt_port_open;
|
||||
|
||||
/*
|
||||
* Last received Advanced Gesture Mode (AGM) packet. An AGM packet
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string_choices.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/input/mt.h>
|
||||
|
||||
|
@ -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);
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (C) 2009 Texas Instruments, Inc
|
||||
*
|
||||
* Author: Miguel Aguilar <miguel.aguilar@ridgerun.com>
|
||||
*/
|
||||
|
||||
#ifndef DAVINCI_KEYSCAN_H
|
||||
#define DAVINCI_KEYSCAN_H
|
||||
|
||||
#include <linux/io.h>
|
||||
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user