diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-05-24 01:13:01 -0700 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-05-24 01:13:01 -0700 |
commit | e644dae645e167d154c0526358940986682a72b0 (patch) | |
tree | 972993c6568085b8d407fc7e13de10f4b93c651d /drivers/input | |
parent | 899c612d74d4a242158a4db20367388d6299c028 (diff) | |
parent | 86809173ce32ef03bd4d0389dfc72df0c805e9c4 (diff) |
Merge branch 'next' into for-linus
Diffstat (limited to 'drivers/input')
114 files changed, 2855 insertions, 1320 deletions
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 33259798081..55f7e57d4e4 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -25,10 +25,6 @@ config INPUT if INPUT -config INPUT_OF_MATRIX_KEYMAP - depends on USE_OF - bool - config INPUT_FF_MEMLESS tristate "Support for memoryless force-feedback devices" help @@ -68,6 +64,19 @@ config INPUT_SPARSEKMAP To compile this driver as a module, choose M here: the module will be called sparse-keymap. +config INPUT_MATRIXKMAP + tristate "Matrix keymap support library" + help + Say Y here if you are using a driver for an input + device that uses matrix keymap. This option is only + useful for out-of-tree drivers since in-tree drivers + select it automatically. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called matrix-keymap. + comment "Userland interfaces" config INPUT_MOUSEDEV diff --git a/drivers/input/Makefile b/drivers/input/Makefile index b173a13a73c..5ca3f631497 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile @@ -10,6 +10,7 @@ input-core-y := input.o input-compat.o input-mt.o ff-core.o obj-$(CONFIG_INPUT_FF_MEMLESS) += ff-memless.o obj-$(CONFIG_INPUT_POLLDEV) += input-polldev.o obj-$(CONFIG_INPUT_SPARSEKMAP) += sparse-keymap.o +obj-$(CONFIG_INPUT_MATRIXKMAP) += matrix-keymap.o obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o obj-$(CONFIG_INPUT_JOYDEV) += joydev.o @@ -24,4 +25,3 @@ obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/ obj-$(CONFIG_INPUT_MISC) += misc/ obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o -obj-$(CONFIG_INPUT_OF_MATRIX_KEYMAP) += of_keymap.o diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 4b2e10d5d64..6c58bfff01a 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -180,7 +180,10 @@ static int evdev_grab(struct evdev *evdev, struct evdev_client *client) static int evdev_ungrab(struct evdev *evdev, struct evdev_client *client) { - if (evdev->grab != client) + struct evdev_client *grab = rcu_dereference_protected(evdev->grab, + lockdep_is_held(&evdev->mutex)); + + if (grab != client) return -EINVAL; rcu_assign_pointer(evdev->grab, NULL); @@ -259,8 +262,7 @@ static int evdev_release(struct inode *inode, struct file *file) struct evdev *evdev = client->evdev; mutex_lock(&evdev->mutex); - if (evdev->grab == client) - evdev_ungrab(evdev, client); + evdev_ungrab(evdev, client); mutex_unlock(&evdev->mutex); evdev_detach_client(evdev, client); @@ -343,7 +345,7 @@ static ssize_t evdev_write(struct file *file, const char __user *buffer, struct input_event event; int retval = 0; - if (count < input_event_size()) + if (count != 0 && count < input_event_size()) return -EINVAL; retval = mutex_lock_interruptible(&evdev->mutex); @@ -355,7 +357,8 @@ static ssize_t evdev_write(struct file *file, const char __user *buffer, goto out; } - do { + while (retval + input_event_size() <= count) { + if (input_event_from_user(buffer + retval, &event)) { retval = -EFAULT; goto out; @@ -364,7 +367,7 @@ static ssize_t evdev_write(struct file *file, const char __user *buffer, input_inject_event(&evdev->handle, event.type, event.code, event.value); - } while (retval + input_event_size() <= count); + } out: mutex_unlock(&evdev->mutex); @@ -395,35 +398,49 @@ static ssize_t evdev_read(struct file *file, char __user *buffer, struct evdev_client *client = file->private_data; struct evdev *evdev = client->evdev; struct input_event event; - int retval = 0; + size_t read = 0; + int error; - if (count < input_event_size()) + if (count != 0 && count < input_event_size()) return -EINVAL; - if (!(file->f_flags & O_NONBLOCK)) { - retval = wait_event_interruptible(evdev->wait, - client->packet_head != client->tail || - !evdev->exist); - if (retval) - return retval; - } + for (;;) { + if (!evdev->exist) + return -ENODEV; - if (!evdev->exist) - return -ENODEV; + if (client->packet_head == client->tail && + (file->f_flags & O_NONBLOCK)) + return -EAGAIN; - while (retval + input_event_size() <= count && - evdev_fetch_next_event(client, &event)) { + /* + * count == 0 is special - no IO is done but we check + * for error conditions (see above). + */ + if (count == 0) + break; - if (input_event_to_user(buffer + retval, &event)) - return -EFAULT; + while (read + input_event_size() <= count && + evdev_fetch_next_event(client, &event)) { - retval += input_event_size(); - } + if (input_event_to_user(buffer + read, &event)) + return -EFAULT; - if (retval == 0 && (file->f_flags & O_NONBLOCK)) - return -EAGAIN; + read += input_event_size(); + } - return retval; + if (read) + break; + + if (!(file->f_flags & O_NONBLOCK)) { + error = wait_event_interruptible(evdev->wait, + client->packet_head != client->tail || + !evdev->exist); + if (error) + return error; |