summaryrefslogtreecommitdiff
path: root/target/linux/s3c24xx/patches-2.6.26/0050-fix-EVIOCGRAB-semantics.patch.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/s3c24xx/patches-2.6.26/0050-fix-EVIOCGRAB-semantics.patch.patch')
-rwxr-xr-xtarget/linux/s3c24xx/patches-2.6.26/0050-fix-EVIOCGRAB-semantics.patch.patch95
1 files changed, 95 insertions, 0 deletions
diff --git a/target/linux/s3c24xx/patches-2.6.26/0050-fix-EVIOCGRAB-semantics.patch.patch b/target/linux/s3c24xx/patches-2.6.26/0050-fix-EVIOCGRAB-semantics.patch.patch
new file mode 100755
index 0000000..5ef328b
--- /dev/null
+++ b/target/linux/s3c24xx/patches-2.6.26/0050-fix-EVIOCGRAB-semantics.patch.patch
@@ -0,0 +1,95 @@
+From 6294c84872b0d26111bdd1b9e5fec41c8a087443 Mon Sep 17 00:00:00 2001
+From: mokopatches <mokopatches@openmoko.org>
+Date: Fri, 25 Jul 2008 22:21:23 +0100
+Subject: [PATCH] fix-EVIOCGRAB-semantics.patch
+
+---
+ drivers/input/evdev.c | 32 +++++++++++++++-----------------
+ 1 files changed, 15 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
+index b32984b..499ffe1 100644
+--- a/drivers/input/evdev.c
++++ b/drivers/input/evdev.c
+@@ -28,7 +28,7 @@ struct evdev {
+ char name[16];
+ struct input_handle handle;
+ wait_queue_head_t wait;
+- struct evdev_client *grab;
++ int *grab;
+ struct list_head client_list;
+ spinlock_t client_lock; /* protects client_list */
+ struct mutex mutex;
+@@ -39,6 +39,7 @@ struct evdev_client {
+ struct input_event buffer[EVDEV_BUFFER_SIZE];
+ int head;
+ int tail;
++ int grab;
+ spinlock_t buffer_lock; /* protects access to buffer, head and tail */
+ struct fasync_struct *fasync;
+ struct evdev *evdev;
+@@ -79,12 +80,8 @@ static void evdev_event(struct input_handle *handle,
+
+ rcu_read_lock();
+
+- client = rcu_dereference(evdev->grab);
+- if (client)
++ list_for_each_entry_rcu(client, &evdev->client_list, node)
+ evdev_pass_event(client, &event);
+- else
+- list_for_each_entry_rcu(client, &evdev->client_list, node)
+- evdev_pass_event(client, &event);
+
+ rcu_read_unlock();
+
+@@ -136,14 +133,15 @@ static int evdev_grab(struct evdev *evdev, struct evdev_client *client)
+ {
+ int error;
+
+- if (evdev->grab)
++ if (client->grab)
+ return -EBUSY;
+
+- error = input_grab_device(&evdev->handle);
+- if (error)
+- return error;
+-
+- rcu_assign_pointer(evdev->grab, client);
++ if (!evdev->grab++) {
++ error = input_grab_device(&evdev->handle);
++ if (error)
++ return error;
++ }
++ client->grab = 1;
+ synchronize_rcu();
+
+ return 0;
+@@ -151,12 +149,12 @@ 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)
++ if (!client->grab)
+ return -EINVAL;
+
+- rcu_assign_pointer(evdev->grab, NULL);
+- synchronize_rcu();
+- input_release_device(&evdev->handle);
++ if (!--evdev->grab && evdev->exist)
++ input_release_device(&evdev->handle);
++ client->grab = 0;
+
+ return 0;
+ }
+@@ -231,7 +229,7 @@ static int evdev_release(struct inode *inode, struct file *file)
+ struct evdev *evdev = client->evdev;
+
+ mutex_lock(&evdev->mutex);
+- if (evdev->grab == client)
++ if (client->grab)
+ evdev_ungrab(evdev, client);
+ mutex_unlock(&evdev->mutex);
+
+--
+1.5.6.3
+